commit 8b2eac9a3da25cf8d266e8e4abc748c194a8edc7 Author: Hombre Date: Tue Jan 21 23:37:36 2014 +0100 Pipette and "On Preview Widgets" branch. See issue 227 The pipette part is already working quite nice but need to be finished. The widgets part needs more work... diff --git a/.hgignore b/.hgignore new file mode 100644 index 000000000..773f0747d --- /dev/null +++ b/.hgignore @@ -0,0 +1,32 @@ +syntax: glob + +*~ +*.orig + +.cproject +.project +.settings + +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..667122205 --- /dev/null +++ b/AUTHORS.txt @@ -0,0 +1,41 @@ + +Project initiator: + + Gábor Horváth + +Developement contributors, in last name alphabetical order: + + Jacques Desmis + Oliver Duis + Maciek Dworak + Michael Ezra + Jean-Christophe Frisch + Steve Herrell + Philippe Hupé + Wolfgang Kuehnel + Guokai Ma + Emil Martinec + Wyatt Olson + Jacek Poplawski + Ilia Popov + 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: + + Thorsten Bartolomäus + Patrik Brunner + Fernando Carello + M. Dávid Gyurkó + Arturs Jekabsons + Lebarhon + Karl Loncarek + Paul Matthijsse + Alberto Righetto + Colin Walker diff --git a/AboutThisBuild.cmake b/AboutThisBuild.cmake new file mode 100644 index 000000000..56cf47fd8 --- /dev/null +++ b/AboutThisBuild.cmake @@ -0,0 +1,39 @@ +# 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 (HG_CMD STREQUAL HG_CMD-NOTFOUND) + message(STATUS "hg command found: ${HG_CMD}") + endif (HG_CMD STREQUAL HG_CMD-NOTFOUND) + + 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 (CACHE_NAME_SUFFIX STREQUAL "") + 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) + endif (CACHE_NAME_SUFFIX STREQUAL "") +else (REL_INFO_FILE STREQUAL REL_INFO_FILE-NOTFOUND) + include("${PROJECT_SOURCE_DIR}/ReleaseInfo.cmake") +endif (REL_INFO_FILE STREQUAL REL_INFO_FILE-NOTFOUND) + +# 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..618926eec --- /dev/null +++ b/AboutThisBuild.txt.in @@ -0,0 +1,14 @@ +Branch: ${HG_BRANCH} +Version: ${HG_VERSION} +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..dcf93e03c --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,356 @@ +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 (CACHE_NAME_SUFFIX "" CACHE STRING "RawTherapee's cache folder suffix (leave empty to use the default suffix, i.e. latesttag)") + +# 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}") + +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) + +# 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}") + 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} + -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 (UNIX) + install (FILES "${PROJECT_SOURCE_DIR}/doc/manpage/rawtherapee.1" DESTINATION "${CMAKE_INSTALL_PREFIX}/share/man/man1") +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..d59c4323c --- /dev/null +++ b/COMPILE.txt @@ -0,0 +1,498 @@ +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/ + 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/ + LIBCANBERRA libcanberra-gtk http://0pointer.de/lennart/projects/libcanberra/ (Linux only) + LCMS2 lcms>=2.0a http://www.littlecms.com/ + 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-r1 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.7 is recommended, 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 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+ + + 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..540181157 --- /dev/null +++ b/RELEASE_NOTES.txt @@ -0,0 +1,54 @@ +RAWTHERAPEE 4.1 RELEASE NOTES +-------------------------------- + +CAVEATS +------- +- Memory requirements +TODO wiki link: Please read http://rawtherapee.com/blog/maximizing-memory-efficiency + +NEW FEATURES +------------ +- dcraw 9.xx +- Added support for + - Cameras +- New DCP profiles for + - Cameras + +Refer to the RawPedia for information about these tools and how to use them: +http://rawpedia.rawtherapee.com/ + +DOCUMENTATION +------------- +http://rawtherapee.com/documentation +http://rawpedia.rawtherapee.com/ + + +REPORTING BUGS +-------------- +TODO wiki link: http://rawtherapee.com/forum/viewtopic.php?f=3&t=3639#p25814 + +LIVE CHAT WITH RT USERS +----------------------- +Network: freenode +Server: chat.freenode.net +Channel #rawtherapee +http://webchat.freenode.net/?randomnick=1&channels=rawtherapee&prompt=1 +TODO wiki link: http://rawtherapee.com/forum/viewtopic.php?f=1&t=945#p4603 + + +SOCIAL NETWORKS +--------------- +Google+ +http://plus.google.com/106783532637761598368 + + +REVISION HISTORY +---------------- +The complete change log is available at: +https://code.google.com/p/rawtherapee/source/list + + +CHANGELOG for 4.1 +---------------------------------------------------------------------- + DATE | CHANGESET | COMMITTER +----------------|---------------|------------------------------------- diff --git a/WindowsEnvironmentSetup.html b/WindowsEnvironmentSetup.html new file mode 100644 index 000000000..de8e4b61d --- /dev/null +++ b/WindowsEnvironmentSetup.html @@ -0,0 +1,45 @@ +

Building Raw Therapee 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 Raw Therapee, 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 raw therapee 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 Raw Therapee.
+If it doesn't work, please tell us about it at the Raw Therapee 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/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/README b/licenses/README new file mode 100644 index 000000000..0fdaf51bf --- /dev/null +++ b/licenses/README @@ -0,0 +1 @@ +This folder contains the licenses and supporting documentation for third party components of RawTherapee. Each file name reflects the portion which it is relevent for. 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/rtdata/CMakeLists.txt b/rtdata/CMakeLists.txt new file mode 100644 index 000000000..e125c373c --- /dev/null +++ b/rtdata/CMakeLists.txt @@ -0,0 +1,97 @@ + +file (GLOB LANGUAGEFILES "languages/*") +file (GLOB SOUNDFILES "sounds/*") +file (GLOB INPUTICCFILES "iccprofiles/input/*") +file (GLOB OUTPUTICCFILES "iccprofiles/output/*") +file (GLOB DCPFILES "dcpprofiles/*") +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") +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 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..ad45cf553 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/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/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..1a3300c13 --- /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-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/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.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-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.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.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-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/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/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.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-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.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.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-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/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/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..98a92f752 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..0bfe65425 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..7bc4ece89 --- /dev/null +++ b/rtdata/languages/Catala @@ -0,0 +1,1407 @@ +#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_FILEDLGFILTERANY;Tots els fitxers +CURVEEDITOR_FILEDLGFILTERCURVE;Fitxers de corba +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: +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_COLORDENOISE;Salta dessorollar color +EXPORT_BYPASS_DEFRINGE;Salta desserrellar +EXPORT_BYPASS_DIRPYRDENOISE;Salta reducció de soroll +EXPORT_BYPASS_DIRPYREQUALIZER;Salta contrast per nivells de detall +EXPORT_BYPASS_LUMADENOISE;Salta dessoroll de luminància +EXPORT_BYPASS_RAW_ALL_ENHANCE;Salta dessoroll/artefactes en post-demosaicat +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 +EXPORT_RESIZEMETHOD;Mètode de canvi de tamany +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_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: 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_USETEMPLATE;Usa plantilla: +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_TAGGING;Tagging +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_B_NA;B = n/a +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_LAB_A_NA;A = n/a +NAVIGATOR_LAB_A_VALUE;A = %1 +NAVIGATOR_LAB_B_NA;B = n/a +NAVIGATOR_LAB_B_VALUE;B = %1 +NAVIGATOR_LAB_L_NA;L = n/a +NAVIGATOR_LAB_L_VALUE;L = %1 +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_V_VALUE;V = %1 +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_METAICMGROUP;Ajustos Metadades/gestió de color +PARTIALPASTE_PERSPECTIVE;Perspectiva +PARTIALPASTE_PREPROCESS_GREENEQUIL;Equilibri verd +PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Aplica filtre píxels cremats/morts +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_ALLENHANCE;Aplica la reducció d'artefactes/soroll en post-demosaicat +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_BLINKCLIPPED;Parpelleig d'àrees perdudes +PREFERENCES_CACHECLEARALL;Esborrar tot +PREFERENCES_CACHECLEARPROFILES;Esborrar perfils +PREFERENCES_CACHECLEARTHUMBS;Esborra minifotos +PREFERENCES_CACHEFORMAT1;Propi (ràpid i millor qualitat) +PREFERENCES_CACHEFORMAT2;JPEG (ocupa menys espai al disc) +PREFERENCES_CACHEMAXENTRIES;Màxim nombre d'entrades a la mem. cau +PREFERENCES_CACHEOPTS;Opcions memòria cau +PREFERENCES_CACHETHUMBFORM;Format del cau en minifoto +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_DATEFORMATFRAME;Format de data +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_GTKTHEME;GTK per omissió +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_PANFACTORFRAME;Ràtio d'amplificació Pan +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_SHOWPROFILESELECTOR;Mostra selector de perfils de processat +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_SQUAREDETAILWINDOW;Quadrar la finestra de detall (ràpid) +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_FILEDLGFILTERANY;Tots els fitxers +PROFILEPANEL_FILEDLGFILTERPP;Perfils de postprocés +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_JPGFILTER;Fitxers 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_TIFFFILTER;Fitxers TIFF +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_GTHARMMEANS1;Tipus armònic 1 +TP_CROP_GTHARMMEANS2;Tipus armònic 2 +TP_CROP_GTHARMMEANS3;Tipus armònic 3 +TP_CROP_GTHARMMEANS4;Tipus armònic 4 +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_EXPOSCORR_LABEL;Raw blanc & punts negres +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_FILEDLGFILTERANY;Tots els fitxers +TP_ICM_FILEDLGFILTERICM;Perfils de color +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_PREFERREDPROFILE;Perfil DCP preferit +TP_ICM_PREFERREDPROFILE_1;Llum de dia +TP_ICM_PREFERREDPROFILE_2;Tungstèn +TP_ICM_PREFERREDPROFILE_3;Fluorescent +TP_ICM_PREFERREDPROFILE_4;Flash +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_BWTONING;Ajust de to B&N +TP_LABCURVE_BWTONING_TIP;Amb l'opció Ajust de tons B/N activada, la cromaticitat Lab i les corbes Cc i Ch no tenen efecte.\nEl tonejament s'assoleix amb les corbes a i b +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_FILEDLGFILTERLCP;Fitxers de correcció de lents +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_HOTDEADPIXFILT;Aplica filtre píxels cremats/morts +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_BLACKONE;Nivell negre: Roig +TP_RAWEXPOS_BLACKS;Nivells negres +TP_RAWEXPOS_BLACKTHREE;Nivell negre: Verd 2 +TP_RAWEXPOS_BLACKTWO;Nivell negre: Blau +TP_RAWEXPOS_BLACKZERO;Nivell negre: verd 1 (leader) +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_ALLENHANCE;Aplica reducció artefactes/soroll post-demosaicat +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_BICUBICSF;Bicúbic (Fluix) +TP_RESIZE_BICUBICSH;Bicúbic (Més intens) +TP_RESIZE_BICUBIC;Bicúbic +TP_RESIZE_BILINEAR;Bilinear +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 +!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_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_UNRANK_TOOLTIP;Unrank\nShortcut: Shift-0 +!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 tones protection +!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 pixels +!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;'CL' curve +!HISTORY_MSG_247;'LH' curve +!HISTORY_MSG_248;'HH' curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +!MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the Next image relative to image open in Editor\nShortcut: Shift-F4\n\nTo navigate to the Next image relative to thumbnail selected in File Browser\nShortcut: F4 +!MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the Previous image relative to image open in Editor\nShortcut: Shift-F3 \n\nTo navigate to the Previous image relative to thumbnail selected in File Browser\nShortcut: F3 +!MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronize the File Browser with the Editor to reveal the thumbnail of the currently open image, and clear filters in File Browser \nShortcut: x\n\nAs above, but without clearing filters in File Browser\nShortcut: y\n(Note that thumbnail of the open file will not be shown if filtered out). +!MAIN_MSG_OPERATIONCANCELLED;Operation cancelled +!MAIN_MSG_PATHDOESNTEXIST;The path\n\n%1\n\ndoesn't exist. Please set a correct path in the Preference window. +!MAIN_MSG_SETPATHFIRST;You have to set a target path first in Preferences\nin order to use this function! +!MAIN_MSG_WRITEFAILED;Failed to write\n\n"%1"\n\nMake sure that the folder exists and that you have write permission to it. +!PARTIALPASTE_CHANNELMIXERBW;Black-and-White +!PARTIALPASTE_COLORAPP;CIE Color Appearance Model 2002 +!PARTIALPASTE_GRADIENT;Graduated filter +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!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_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_CUSTPROFBUILDKEYFORMAT;Keys format +!PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Name +!PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID +!PREFERENCES_D50;5000K +!PREFERENCES_D55;5500K +!PREFERENCES_D60;6000K +!PREFERENCES_D65;6500K +!PREFERENCES_FLUOF2;Fluorescent F2 +!PREFERENCES_FLUOF7;Fluorescent F7 +!PREFERENCES_FLUOF11;Fluorescent F11 +!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;Output device's Yb luminance (%) +!PREFERENCES_RGBDTL_LABEL;Max number of threads for Noise Reduction +!PREFERENCES_RGBDTL_TOOLTIP;Noise Reduction requires a baseline of about 128MB RAM for a 10MPix image or 512MB for a 40MPix image, and additionally 128MB RAM per thread. The more threads run in parallel, the faster the computation. Leave the setting at "0" to automatically use as many threads as possible. +!PREFERENCES_TAB_PERFORMANCE;Performance +!PREFERENCES_USEBUNDLEDPROFILES;Use bundled profiles +!PREFERENCES_VIEW;Output device's white balance (monitor, TV, projector, viewing, etc.) +!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_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing channel-mixer +!TP_BWMIX_BLUE;Blue +!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;Modify luminance in function of hue\nPay attention to extreme values that may cause artifacts +!TP_BWMIX_CYAN;Cyan +!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 simulate shots taken with a colored filter placed in front of the lens. Colored filters reduce transmission of specific range of colors and correspondingly affect their lightness. E.g. a Red filter darkens Blue skies. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_BLUE;Blue Channel +!TP_BWMIX_GAM_GREEN;Green Channel +!TP_BWMIX_GAM_RED;Red Channel +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each channel RGB +!TP_BWMIX_GREEN;Green +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MAGENTA;Magenta +!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 (filter, channel-mixer) to default +!TP_BWMIX_ORANGE;Orange +!TP_BWMIX_PURPLE;Purple +!TP_BWMIX_RED;Red +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all of the mixer options\nTotal displays the sum of RGB values actually applied:\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 (films, landscape, ...) or manual settings of channel-mixer +!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;Channel-Mixer absolute RGB +!TP_BWMIX_SET_RGBREL;Channel-Mixer relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Channel-Mixer absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Channel-Mixer 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_BWMIX_YELLOW;Yellow +!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) RT 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.\n 0=no effect 1=median 2=gaussian.\n\nThese artifacts are due to limitations of CIECAM02. Alternatively, adjust the image to avoid very dark shadows. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from Lab and RGB brightness +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from Lab and RGB colorfulness +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from Lab and RGB saturation +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from Lab 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 Lab and RGB contrast +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from Lab and RGB contrast +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L (Lab) 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 (Lab) 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 Lab values before CIECAM02 adjustments +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RT 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 (Lab) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in Lab 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 Lab and RGB lightness +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model\n\nWB [RT] + [output]:\nRT's white balance is used for the scene, CIECAM02 is set to D50, the output device's white balance is set in Preferences > Color Management\n\nWB [RT+CAT02] + [output]:\nRT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences +!TP_COLORAPP_RSTPRO;Red & skin tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin tones protection (sliders and curves) +!TP_COLORAPP_SHARPCIE;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe with Q/C +!TP_COLORAPP_SHARPCIE_TOOLTIP;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe will use CIECAM02 if enabled. +!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;Change tones and colors to take into account the viewing conditions of the output device\n\nAverage:\nAverage light environment (standard)\nThe image will not change\n\nDim:\nDim environment (TV)\nThe image will become slighty dark\n\nDark:\nDark environment (projector)\nThe image will become more dark\n\nExtremly Dark:\nExtremly dark environment (cutsheet)\nThe image will become very dark +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if source 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 Lab 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_DIRPYRDENOISE_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on gamma of the input color profile. Gamma of sRGB is assumed, thus if input image is in color profile of a different gamma, luminance noise reduction will vary. +!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_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or Lab methods can be used.\n\nFor non-raw images Lab method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_PERF;RGB mode (raw images) +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGB;RGB +!TP_EPD_TOOLTIP;Tone mapping is possible via Lab mode (standard) and CIECAM02 mode.\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_GENERAL_11SCALE_TOOLTIP;The effect of this tool or some of its sub-component is only visible at 1:1 preview scale. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Rotation anchor point X: -100=left edge, 0=center, +100=right edge +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Rotation anchor point Y: -100=top edge, 0=center, +100=bottom edge +!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 automatic exposure +!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_TOOLTIP;Save the linear TIFF image before the input profile is applied. Result can be used for calibration purposes, 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: 0=corners only, 50=halfway to center, 100=to center +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness: 0=rectangle, 50=fitted ellipse, 100=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. Higher = more, lower = less. +!TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Try to suppress hot and dead pixels +!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 +!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_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 used with CIECAM02. If difference is observed, adjust to taste. +!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 diff --git a/rtdata/languages/Chinese (Simplified) b/rtdata/languages/Chinese (Simplified) new file mode 100644 index 000000000..a5956e78f --- /dev/null +++ b/rtdata/languages/Chinese (Simplified) @@ -0,0 +1,1443 @@ +#01 2008-11-06 Yang Gao (grantyale) +#02 Updated by Forrest Sun + +ADJUSTER_RESET_TO_DEFAULT;重置缺省参数 +CURVEEDITOR_FILEDLGFILTERANY;任意文件 +CURVEEDITOR_FILEDLGFILTERCURVE;曲线文件 +CURVEEDITOR_LINEAR;线性 +CURVEEDITOR_LOADDLGLABEL;正读取曲线... +CURVEEDITOR_SAVEDLGLABEL;正保存曲线... +CURVEEDITOR_TOOLTIPLINEAR;重置曲线 +CURVEEDITOR_TOOLTIPLOAD;读取曲线 +CURVEEDITOR_TOOLTIPSAVE;保存曲线 +EXIFFILTER_APERTURE;光圈 +EXIFFILTER_CAMERA;相机 +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;子文件夹 +FILEBROWSER_APPLYPROFILE;应用配置 +FILEBROWSER_CLEARPROFILE;清空配置 +FILEBROWSER_COPYPROFILE;复制配置 +FILEBROWSER_DELETEDLGLABEL;确认删除 +FILEBROWSER_DELETEDLGMSG;确定删除所选的%1个文件? +FILEBROWSER_EMPTYTRASHHINT;永久清空垃圾箱 +FILEBROWSER_EMPTYTRASH;清空垃圾箱 +FILEBROWSER_PARTIALPASTEPROFILE;选择性粘贴 +FILEBROWSER_PASTEPROFILE;粘贴配置 +FILEBROWSER_POPUPCANCELJOB;取消任务 +FILEBROWSER_POPUPMOVEEND;移动到队列尾部 +FILEBROWSER_POPUPMOVEHEAD;移动到队列头部 +FILEBROWSER_POPUPOPEN;打开 +FILEBROWSER_POPUPPROCESS;放入队列 +FILEBROWSER_POPUPREMOVE;从文件系统中移除 +FILEBROWSER_POPUPRENAME;重命名 +FILEBROWSER_POPUPSELECTALL;全部选中 +FILEBROWSER_POPUPTRASH;移动到垃圾箱 +FILEBROWSER_POPUPUNRANK;取消星级 +FILEBROWSER_POPUPUNTRASH;从垃圾箱中移除 +FILEBROWSER_RENAMEDLGLABEL;文件重命名 +FILEBROWSER_RENAMEDLGMSG;将"%1"更名为: +FILEBROWSER_SHOWDIRHINT;显示文件夹中所有图片 +FILEBROWSER_SHOWRANK1HINT;显示1星图片 +FILEBROWSER_SHOWRANK2HINT;显示2星图片 +FILEBROWSER_SHOWRANK3HINT;显示3星图片 +FILEBROWSER_SHOWRANK4HINT;显示4星图片 +FILEBROWSER_SHOWRANK5HINT;显示5星图片 +FILEBROWSER_SHOWTRASHHINT;显示垃圾箱内容 +FILEBROWSER_SHOWUNRANKHINT;显示未评星图片 +FILEBROWSER_STARTPROCESSINGHINT;开始处理或保存队列中的图片 +FILEBROWSER_STARTPROCESSING;开始处理 +FILEBROWSER_STOPPROCESSINGHINT;停止处理图片 +FILEBROWSER_STOPPROCESSING;停止处理 +FILEBROWSER_THUMBSIZE;缩略图大小 +FILEBROWSER_ZOOMINHINT;增大缩略图 +FILEBROWSER_ZOOMOUTHINT;减小缩略图 +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;显示/隐藏 蓝色直方图 +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;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;图片创作日期,格式:年月日补零(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_PREFERENCES;参数设置 +MAIN_BUTTON_SAVEAS;为... +MAIN_BUTTON_SAVE;保存图片 +MAIN_BUTTON_SENDTOEDITOR;发送到编辑器 +MAIN_FRAME_BATCHQUEUE;批量处理序列 +MAIN_FRAME_FILEBROWSER;文件浏览 +MAIN_FRAME_PLACES;位置 +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_RECENT;最近使用的文件夹 +MAIN_MSG_ALREADYEXISTS;该文件已存在 +MAIN_MSG_CANNOTLOAD;无法加载图片 +MAIN_MSG_CANNOTSAVE;文件保存中出错 +MAIN_MSG_CANNOTSTARTEDITOR;无法启动编辑器 +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;请在“首选项“对话框设置正确的路径。 +MAIN_MSG_QOVERWRITE;是否覆盖? +MAIN_TAB_COLOR;色彩 +MAIN_TAB_DETAIL;详细 +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;曝光 +MAIN_TAB_FILTER;Filter +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;元数据 +MAIN_TAB_TAGGING;标签 +MAIN_TAB_TRANSFORM;转换 +MAIN_TOOLTIP_HIDEHP;显示/隐藏左面板 (包含历史, 快捷键: H) +MAIN_TOOLTIP_INDCLIPPEDH;高光溢出提示 +MAIN_TOOLTIP_INDCLIPPEDS;阴影不足提示 +MAIN_TOOLTIP_QINFO;图片快捷信息 +PARTIALPASTE_BASICGROUP;基本设置 +PARTIALPASTE_CACORRECTION;色彩校正 +PARTIALPASTE_COARSETRANS;90度旋转/翻转 +PARTIALPASTE_COLORGROUP;色彩相关设定 +PARTIALPASTE_COMPOSITIONGROUP;构图设置 +PARTIALPASTE_CROP;剪裁 +PARTIALPASTE_DIALOGLABEL;选择性粘贴配置 +PARTIALPASTE_DISTORTION;形变校正 +PARTIALPASTE_EXIFCHANGES;对exif所做的修改 +PARTIALPASTE_EXPOSURE;曝光 +PARTIALPASTE_ICMSETTINGS;ICM 设置 +PARTIALPASTE_IPTCINFO;IPTC 信息 +PARTIALPASTE_LENSGROUP;镜头相关设置 +PARTIALPASTE_LUMACURVE;亮度曲线 +PARTIALPASTE_METAICMGROUP;元数据/ICM 设置 +PARTIALPASTE_RESIZE;缩放 +PARTIALPASTE_ROTATION;旋转 +PARTIALPASTE_SHADOWSHIGHLIGHTS;阴影/高光 +PARTIALPASTE_SHARPENING;锐化 +PARTIALPASTE_VIGNETTING;暗角修正 +PARTIALPASTE_WHITEBALANCE;白平衡 +PREFERENCES_APPLNEXTSTARTUP;下次启动生效 +PREFERENCES_BLINKCLIPPED;高光区域闪烁 +PREFERENCES_CACHECLEARALL;全部清除 +PREFERENCES_CACHECLEARPROFILES;清除配置 +PREFERENCES_CACHECLEARTHUMBS;清除缩略图 +PREFERENCES_CACHEFORMAT1;专有格式 (快速高质量) +PREFERENCES_CACHEFORMAT2;JPEG (较小文件) +PREFERENCES_CACHEMAXENTRIES;最大缓存数量 +PREFERENCES_CACHEOPTS;缓存选项 +PREFERENCES_CACHETHUMBFORM;缩略图缓存格式 +PREFERENCES_CACHETHUMBHEIGHT;最大缩略图高度 +PREFERENCES_CLEARDLG_LINE1;正在清空缓存 +PREFERENCES_CLEARDLG_LINE2;可能需要数秒钟时间。 +PREFERENCES_CLEARDLG_TITLE;请稍等 +PREFERENCES_CLIPPINGIND;高光溢出提示 +PREFERENCES_CMETRICINTENT;色彩模式 +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_DMETHOD;方式 +PREFERENCES_EDITORCMDLINE;其他命令行 +PREFERENCES_EXTERNALEDITOR;外部编辑器 +PREFERENCES_FALSECOLOR;虚假色彩压缩步骤 +PREFERENCES_FBROWSEROPTS;文件浏览选项 +PREFERENCES_FILEFORMAT;文件格式 +PREFERENCES_FORIMAGE;用于图片文件 +PREFERENCES_FORRAW;用于Raw文件 +PREFERENCES_GIMPPATH;GIMP安装文件夹 +PREFERENCES_GTKTHEME;GTK默认 +PREFERENCES_HLTHRESHOLD;高光溢出阈值 +PREFERENCES_ICCDIR;ICC配置路径 +PREFERENCES_IMPROCPARAMS;缺省图片处理参数 +PREFERENCES_INTENT_ABSOLUTE;绝对色彩模式 +PREFERENCES_INTENT_PERCEPTUAL;感知模式 +PREFERENCES_INTENT_RELATIVE;相对色彩模式 +PREFERENCES_INTENT_SATURATION;饱和度 +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_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;图片处理 +PROFILEPANEL_FILEDLGFILTERANY;任意文件 +PROFILEPANEL_FILEDLGFILTERPP;处理参数配置 +PROFILEPANEL_LABEL;处理参数配置 +PROFILEPANEL_LOADDLGLABEL;加载处理参数为... +PROFILEPANEL_PCUSTOM;自定义 +PROFILEPANEL_PFILE;由文件 +PROFILEPANEL_PLASTSAVED;上次保存 +PROFILEPANEL_SAVEDLGLABEL;保存处理参数为... +PROFILEPANEL_TOOLTIPCOPY;将当前配置复制到剪贴板 +PROFILEPANEL_TOOLTIPLOAD;由文件加载配置 +PROFILEPANEL_TOOLTIPPASTE;从剪贴板粘贴配置 +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文件保存中... +PROGRESSDLG_LOADING;正在读取文件... +PROGRESSDLG_PROCESSING;正在处理图像... +PROGRESSDLG_SAVING;保存文件中... +QINFO_ISO;感光度 +QINFO_NOEXIF;Exif数据不可用. +SAVEDLG_FILEFORMAT;文件格式 +SAVEDLG_JPEGQUAL;JPEG质量 +SAVEDLG_JPGFILTER;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;放入队列 +SAVEDLG_SAVEIMMEDIATELY;立即保存 +SAVEDLG_SAVESPP;随图片保存处理参数 +SAVEDLG_TIFFFILTER;TIFF文件 +TOOLBAR_TOOLTIP_CROP;剪裁选择 (快捷键: C) +TOOLBAR_TOOLTIP_HAND;手形工具 (快捷键: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;基准线选择 (快捷键: S) +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_COARSETRAF_DEGREE;角度: +TP_COARSETRAF_TOOLTIP_HFLIP;水平翻转 +TP_COARSETRAF_TOOLTIP_ROTLEFT;左转 +TP_COARSETRAF_TOOLTIP_ROTRIGHT;右转 +TP_COARSETRAF_TOOLTIP_VFLIP;竖直翻转 +TP_COLORBOOST_ACHANNEL;通道 "a" +TP_COLORBOOST_AMOUNT;程度 +TP_COLORBOOST_AVOIDCOLORCLIP;避免色彩溢出 +TP_COLORBOOST_BCHANNEL;通道 "b" +TP_COLORBOOST_CHANNEL;通道 +TP_COLORBOOST_CHSEPARATE;分解 +TP_COLORBOOST_ENABLESATLIMITER;启用饱和度限制 +TP_COLORBOOST_LABEL;色彩增强 +TP_COLORBOOST_SATLIMIT;饱和度限制 +TP_COLORDENOISE_EDGESENSITIVE;边缘敏感度 +TP_COLORDENOISE_EDGETOLERANCE;边缘容差 +TP_COLORDENOISE_LABEL;色彩噪点抑制 +TP_COLORDENOISE_RADIUS;半径 +TP_COLORSHIFT_BLUEYELLOW;蓝-黄 +TP_COLORSHIFT_GREENMAGENTA;绿-洋红 +TP_COLORSHIFT_LABEL;色彩偏移 +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;比例: +TP_CROP_GTDIAGONALS;对角线法则 +TP_CROP_GTHARMMEANS1;黄金点 1 +TP_CROP_GTHARMMEANS2;黄金点 2 +TP_CROP_GTHARMMEANS3;黄金点 3 +TP_CROP_GTHARMMEANS4;黄金点 4 +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模式混合 +TP_HLREC_COLOR;色彩延伸 +TP_HLREC_LABEL;高光还原 +TP_HLREC_LUMINANCE;亮度还原 +TP_HLREC_METHOD;方式: +TP_ICM_FILEDLGFILTERANY;任意文件 +TP_ICM_FILEDLGFILTERICM;ICC配置文件 +TP_ICM_GAMMABEFOREINPUT;配置应用Gamma校正 +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;保存参考图片用于生成配置信息 +TP_ICM_WORKINGPROFILE;当前配置 +TP_LUMACURVE_BLACKLEVEL;黑点 +TP_LUMACURVE_BRIGHTNESS;亮度 +TP_LUMACURVE_COMPRHIGHLIGHTS;高光压缩 +TP_LUMACURVE_COMPRSHADOWS;阴影压缩 +TP_LUMACURVE_CONTRAST;对比度 +TP_LUMACURVE_CURVEEDITOR;亮度曲线 +TP_LUMACURVE_LABEL;亮度曲线 +TP_RESIZE_BICUBICSF;双三次 (柔化) +TP_RESIZE_BICUBICSH;双三次 (锐化) +TP_RESIZE_BICUBIC;双三次 +TP_RESIZE_BILINEAR;双线性 +TP_RESIZE_H;高: +TP_RESIZE_LABEL;调整大小 +TP_RESIZE_METHOD;方式: +TP_RESIZE_NEAREST;最近点 +TP_RESIZE_SCALE;比例 +TP_RESIZE_W;宽: +TP_ROTATE_AUTOCROP;自动剪裁 +TP_ROTATE_DEGREE;角度 +TP_ROTATE_FILL;填充 +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;白平衡采样 +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_CURVES;Curves +!CURVEEDITOR_CURVE;Curve +!CURVEEDITOR_CUSTOM;Custom +!CURVEEDITOR_DARKS;Darks +!CURVEEDITOR_HIGHLIGHTS;Highlights +!CURVEEDITOR_LIGHTS;Lights +!CURVEEDITOR_MINMAXCPOINTS;Minima/Maxima control points +!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 +!EXIFFILTER_EXPOSURECOMPENSATION;Exposure Compensation (EV) +!EXIFFILTER_FILETYPE;File Type +!EXIFFILTER_METADATAFILTER;Enable Metadata Filters +!EXPORT_BYPASS_ALL;Select / Unselect All +!EXPORT_BYPASS_COLORDENOISE;Bypass Color denoise +!EXPORT_BYPASS_DEFRINGE;Bypass Defringe +!EXPORT_BYPASS_DIRPYRDENOISE;Bypass Noise Reduction +!EXPORT_BYPASS_DIRPYREQUALIZER;Bypass Contrast by Detail Levels +!EXPORT_BYPASS_LUMADENOISE;Bypass Luma denoise +!EXPORT_BYPASS_RAW_ALL_ENHANCE;Bypass Post Demosaic Artifact/Noise Reduction +!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 +!EXPORT_RESIZEMETHOD;Resize 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.\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\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_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_POPUPRANK;Rank +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!FILEBROWSER_QUERYHINT;Type a partial filename to search for or a comma-separated list.\nE.g. 1001,1004,1199 \n\nCtrl-F to focus to the Find text box.\nEnter to commence search.\nEsc to clear.\nShift-Esc to remove focus. +!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.\nShortcut: i\n\nShortcut in Single Editor Tab Mode: Alt-i +!FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show images recently saved.\nShortcut: Alt-7 +!FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show images not recently saved.\nShortcut: Alt-6 +!FILEBROWSER_SHOWUNCOLORHINT;Show images without Color label.\nShortcut: Alt-0 +!FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +!FILEBROWSER_UNRANK_TOOLTIP;Unrank\nShortcut: Shift-0 +!FILEBROWSER_USETEMPLATE;Use template: +!GENERAL_AFTER;After +!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\nClick right mouse button on image preview to freeze/unfreeze +!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram +!HISTOGRAM_TOOLTIP_FULL;Toggle full (on) or scaled (off) 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;Lab - Chromaticity +!HISTORY_MSG_96;'a' Curve +!HISTORY_MSG_97;'b' Curve +!HISTORY_MSG_98;Demosaicing Method +!HISTORY_MSG_99;Hot/Dead pixel filter +!HISTORY_MSG_100;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;Resizing applies to +!HISTORY_MSG_111;Lab - Avoid color shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;Lab - Protection +!HISTORY_MSG_114;DCB Iterations +!HISTORY_MSG_115;False Color Suppression +!HISTORY_MSG_116;DCB Enhancement +!HISTORY_MSG_117;Raw Red CA Correction +!HISTORY_MSG_118;Raw Blue CA Correction +!HISTORY_MSG_119;Line Noise Filter +!HISTORY_MSG_120;Green Equilibration +!HISTORY_MSG_121;Raw Auto CA +!HISTORY_MSG_122;Dark Frame Auto Select +!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 Select +!HISTORY_MSG_128;Flat Field Blur Radius +!HISTORY_MSG_129;Flat Field Blur Type +!HISTORY_MSG_130;Auto Distorion +!HISTORY_MSG_131;Noise Reduction Luma +!HISTORY_MSG_132;Noise Reduction 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;Edges Sharpening +!HISTORY_MSG_147;ES - Luminance Only +!HISTORY_MSG_148;Microcontrast +!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_150;Post Demosaic Artifact/Noise Reduction +!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;'CC' curve +!HISTORY_MSG_169;'CH' curve +!HISTORY_MSG_170;Vib - Curve +!HISTORY_MSG_171;'LC' curve +!HISTORY_MSG_172;Lab - 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 tones protection +!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 pixels +!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;'CL' curve +!HISTORY_MSG_247;'LH' curve +!HISTORY_MSG_248;'HH' curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +!MAIN_BUTTON_FULLSCREEN;Fullscreen +!MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the Next image relative to image open in Editor\nShortcut: Shift-F4\n\nTo navigate to the Next image relative to thumbnail selected in File Browser\nShortcut: F4 +!MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the Previous image relative to image open in Editor\nShortcut: Shift-F3 \n\nTo navigate to the Previous image relative to thumbnail selected in File Browser\nShortcut: F3 +!MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronize the File Browser with the Editor to reveal the thumbnail of the currently open image, and clear filters in File Browser \nShortcut: x\n\nAs above, but without clearing filters in File Browser\nShortcut: y\n(Note that thumbnail of the open file 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\ndoesn't exist. Please set a correct path in the Preference window. +!MAIN_MSG_SETPATHFIRST;You have to set a target path first in Preferences\nin order to use this function! +!MAIN_MSG_WRITEFAILED;Failed to write\n\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_METADATA_TOOLTIP;Shortcut: Alt-m +!MAIN_TAB_RAW;Raw +!MAIN_TAB_RAW_TOOLTIP;Shortcut: Alt-r +!MAIN_TAB_TRANSFORM_TOOLTIP;Shortcut: Alt-t +!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 10-30%\n\nPreview is rendered slower with Focus Mask turned on. +!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_NA;B = n/a +!NAVIGATOR_B_VALUE;B = %1 +!NAVIGATOR_G_NA;G = n/a +!NAVIGATOR_G_VALUE;G = %1 +!NAVIGATOR_H_NA;H = n/a +!NAVIGATOR_H_VALUE;H = %1 +!NAVIGATOR_LAB_A_NA;a = n/a +!NAVIGATOR_LAB_A_VALUE;a = %1 +!NAVIGATOR_LAB_B_NA;b = n/a +!NAVIGATOR_LAB_B_VALUE;b = %1 +!NAVIGATOR_LAB_L_NA;L = n/a +!NAVIGATOR_LAB_L_VALUE;L = %1 +!NAVIGATOR_R_NA;R = n/a +!NAVIGATOR_R_VALUE;R = %1 +!NAVIGATOR_S_NA;S = n/a +!NAVIGATOR_S_VALUE;S = %1 +!NAVIGATOR_V_NA;V = n/a +!NAVIGATOR_V_VALUE;V = %1 +!NAVIGATOR_XY_FULL;Width = %1, Height = %2 +!NAVIGATOR_XY_NA;x = n/a, y = n/a +!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;CIE Color Appearance Model 2002 +!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_EVERYTHING;Everything +!PARTIALPASTE_FLATFIELDAUTOSELECT;Flat field auto selection +!PARTIALPASTE_FLATFIELDBLURRADIUS;Flat field blur radius +!PARTIALPASTE_FLATFIELDBLURTYPE;Flat field blur type +!PARTIALPASTE_FLATFIELDFILE;Flat field file +!PARTIALPASTE_GRADIENT;Graduated filter +!PARTIALPASTE_HSVEQUALIZER;HSV equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!PARTIALPASTE_LABCURVE;Lab adjustments +!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_PERSPECTIVE;Perspective +!PARTIALPASTE_PREPROCESS_GREENEQUIL;Green equilibration +!PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Apply hot/dead 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_ALLENHANCE;Post-demosaic artifact/noise reduction +!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 +!PREFERENCES_ADD;Add +!PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!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_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_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 scipts 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_DATEFORMATFRAME;Date Format +!PREFERENCES_DIRDARKFRAMES;Dark frames directory +!PREFERENCES_EDITORLAYOUT;Editor Layout +!PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar (de-select for low resolution display) +!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_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;Output device's Yb luminance (%) +!PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogram in left panel +!PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Show embedded JPEG thumbnail if raw is unedited +!PREFERENCES_LANGAUTODETECT;Use OS language setting +!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_MULTITABDUALMON;Multiple Editor Tabs Mode (if available on second monitor) +!PREFERENCES_MULTITAB;Multiple Editor Tabs Mode +!PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails +!PREFERENCES_OVERWRITEOUTPUTFILE;Overwrite existing output files +!PREFERENCES_PANFACTORFRAME;Pan Rate Amplification +!PREFERENCES_PANFACTORLABEL;Factor +!PREFERENCES_PROPERTY;Property +!PREFERENCES_RGBDTL_LABEL;Max number of threads for Noise Reduction +!PREFERENCES_RGBDTL_TOOLTIP;Noise Reduction requires a baseline of about 128MB RAM for a 10MPix image or 512MB for a 40MPix image, and additionally 128MB RAM per thread. The more threads run in parallel, the faster the computation. Leave the setting at "0" to automatically use as many threads as possible. +!PREFERENCES_SELECTFONT;Select font +!PREFERENCES_SET;Set +!PREFERENCES_SHOWEXPOSURECOMPENSATION;Append exposure compensation +!PREFERENCES_SHOWPROFILESELECTOR;Show processing profile selector +!PREFERENCES_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs +!PREFERENCES_SINGLETAB;Single Editor Tab Mode +!PREFERENCES_SLIMUI;Slim interface +!PREFERENCES_SND_BATCHQUEUEDONE;Queue processing done +!PREFERENCES_SND_HELP;Either enter filepath or nothing (for no sound).\nOn Windows use "SystemDefault", "SystemAsterisk" etc. for system sounds.\nOn Linux use "complete", "window-attention" etc. for system sounds. +!PREFERENCES_SND_LNGEDITPROCDONE;Editor processing done +!PREFERENCES_SND_TRESHOLDSECS;after secs +!PREFERENCES_SQUAREDETAILWINDOW;Square detail window (faster) +!PREFERENCES_TAB_PERFORMANCE;Performance +!PREFERENCES_TAB_SOUND;Sounds +!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_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_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing channel-mixer +!TP_BWMIX_BLUE;Blue +!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;Modify luminance in function of hue\nPay attention to extreme values that may cause artifacts +!TP_BWMIX_CYAN;Cyan +!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 simulate shots taken with a colored filter placed in front of the lens. Colored filters reduce transmission of specific range of colors and correspondingly affect their lightness. E.g. a Red filter darkens Blue skies. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_BLUE;Blue Channel +!TP_BWMIX_GAM_GREEN;Green Channel +!TP_BWMIX_GAM_RED;Red Channel +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each channel RGB +!TP_BWMIX_GREEN;Green +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MAGENTA;Magenta +!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 (filter, channel-mixer) to default +!TP_BWMIX_ORANGE;Orange +!TP_BWMIX_PURPLE;Purple +!TP_BWMIX_RED;Red +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all of the mixer options\nTotal displays the sum of RGB values actually applied:\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 (films, landscape, ...) or manual settings of channel-mixer +!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;Channel-Mixer absolute RGB +!TP_BWMIX_SET_RGBREL;Channel-Mixer relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Channel-Mixer absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Channel-Mixer 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_BWMIX_YELLOW;Yellow +!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) RT 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.\n 0=no effect 1=median 2=gaussian.\n\nThese artifacts are due to limitations of CIECAM02. Alternatively, adjust the image to avoid very dark shadows. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from Lab and RGB brightness +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from Lab and RGB colorfulness +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from Lab and RGB saturation +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from Lab 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 Lab and RGB contrast +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from Lab and RGB contrast +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L (Lab) 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 (Lab) 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 Lab values before CIECAM02 adjustments +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RT 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 (Lab) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in Lab 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 Lab and RGB lightness +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model\n\nWB [RT] + [output]:\nRT's white balance is used for the scene, CIECAM02 is set to D50, the output device's white balance is set in Preferences > Color Management\n\nWB [RT+CAT02] + [output]:\nRT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences +!TP_COLORAPP_RSTPRO;Red & skin tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin tones protection (sliders and curves) +!TP_COLORAPP_SHARPCIE;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe with Q/C +!TP_COLORAPP_SHARPCIE_TOOLTIP;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe will use CIECAM02 if enabled. +!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;Change tones and colors to take into account the viewing conditions of the output device\n\nAverage:\nAverage light environment (standard)\nThe image will not change\n\nDim:\nDim environment (TV)\nThe image will become slighty dark\n\nDark:\nDark environment (projector)\nThe image will become more dark\n\nExtremly Dark:\nExtremly dark environment (cutsheet)\nThe image will become very dark +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if source 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 Lab 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_CROP_GTEPASSPORT;Biometric Passport +!TP_CROP_GTFRAME;Frame +!TP_CROP_GTGRID;Grid +!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_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_CHROMA;Chrominance - Master +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on gamma of the input color profile. Gamma of sRGB is assumed, thus if input image is in color profile of a different gamma, luminance noise reduction will vary. +!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_LAB;Lab +!TP_DIRPYRDENOISE_LDETAIL;Luminance Detail +!TP_DIRPYRDENOISE_LUMA;Luminance +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or Lab methods can be used.\n\nFor non-raw images Lab method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_PERF;RGB mode (raw images) +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGB;RGB +!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_THRESHOLD;Threshold +!TP_DISTORTION_AUTO;Auto Distortion Correction +!TP_DISTORTION_AUTO_TIP;(Exprimental) Correct lens distortion automatically for some cameras (Micro 4/3, some compact digital cameras, etc.) +!TP_EPD_EDGESTOPPING;Edge Stopping +!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 via Lab mode (standard) and CIECAM02 mode.\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_EXPOSCORR_LABEL;Raw White & Black Points +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggle execution of auto levels to automatically set parameter values based on image analysis\nEnable Highlight Reconstruction if necessary +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in auto level's 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 following section of the manual to learn how to achieve the best results with double curves:\nThe Toolbox > Exposure Tab > Exposure Panel > Tone Curve +!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_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!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_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 effect of this tool or some of its sub-component is only visible at 1:1 preview scale. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Rotation anchor point X: -100=left edge, 0=center, +100=right edge +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Rotation anchor point Y: -100=top edge, 0=center, +100=bottom edge +!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 automatic exposure +!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 blown 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 simple color matrix by dcraw, enhanced RawTherapee version (whichever is available based on camera model) or embedded in 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. Use only in special cases. +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. Result can be used for calibration purposes, 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;Lab 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;Can be used with the Chromaticity slider and the CC curve. +!TP_LENSGEOM_AUTOCROP;Auto Crop +!TP_LENSGEOM_FILL;Auto fill +!TP_LENSGEOM_LABEL;Lens / Geometry +!TP_LENSPROFILE_FILEDLGFILTERLCP;Lens correction files +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;CA Correction +!TP_LENSPROFILE_USEDIST;Distortion correction +!TP_LENSPROFILE_USEVIGN;Vignetting correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset 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: 0=corners only, 50=halfway to center, 100=to center +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness: 0=rectangle, 50=fitted ellipse, 100=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. Higher = more, lower = less. +!TP_PREPROCESS_GREENEQUIL;Green Equilibration +!TP_PREPROCESS_HOTDEADPIXFILT;Hot/Dead pixel filter +!TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Try to suppress hot and dead 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_BLACKONE;Black Level: Red +!TP_RAWEXPOS_BLACKS;Black Levels +!TP_RAWEXPOS_BLACKTHREE;Black Level: Green 2 +!TP_RAWEXPOS_BLACKTWO;Black Level: Blue +!TP_RAWEXPOS_BLACKZERO;Black Level: Green 1 (lead) +!TP_RAWEXPOS_LINEAR;White Point Correction +!TP_RAWEXPOS_PRESER;Highlight Preservation +!TP_RAWEXPOS_TWOGREEN;Link greens +!TP_RAW_ALLENHANCE;Post-Demosaic Artifact/Noise Reduction +!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 +!TP_RAW_FALSECOLOR;False Color Suppression Steps +!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_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 used 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_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_ZOOMFITSCREEN;Fit to screen\nShortcut: f +!ZOOMPANEL_ZOOMIN;Zoom In\nShortcut: + +!ZOOMPANEL_ZOOMOUT;Zoom Out\nShortcut: - diff --git a/rtdata/languages/Chinese (Traditional) b/rtdata/languages/Chinese (Traditional) new file mode 100644 index 000000000..809000b9b --- /dev/null +++ b/rtdata/languages/Chinese (Traditional) @@ -0,0 +1,1444 @@ +#01 2008-07-29 Mingjui Liao + +ADJUSTER_RESET_TO_DEFAULT;重置預設參數 +BATCHQUEUE_AUTOSTART;Auto start +CURVEEDITOR_FILEDLGFILTERANY;任意文件 +CURVEEDITOR_FILEDLGFILTERCURVE;曲線檔 +CURVEEDITOR_LINEAR;線性 +CURVEEDITOR_LOADDLGLABEL;正載入曲線... +CURVEEDITOR_SAVEDLGLABEL;正儲存曲線... +CURVEEDITOR_TOOLTIPLINEAR;重置曲線 +CURVEEDITOR_TOOLTIPLOAD;載入曲線 +CURVEEDITOR_TOOLTIPSAVE;儲存曲線 +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_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_SAVEAS;為... +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_TAGGING;Tagging +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_LUMACURVE;Luminance curve +PARTIALPASTE_METAICMGROUP;Metadata/ICM settings +PARTIALPASTE_RESIZE;Resize +PARTIALPASTE_ROTATION;Rotation +PARTIALPASTE_SHADOWSHIGHLIGHTS;Shadows/Highlights +PARTIALPASTE_SHARPENING;Sharpening +PARTIALPASTE_VIGNETTING;Vignetting correction +PARTIALPASTE_WHITEBALANCE;White balance +PREFERENCES_APPLNEXTSTARTUP;下次啟動生效 +PREFERENCES_BLINKCLIPPED;高光區域閃爍 +PREFERENCES_CACHECLEARALL;Clear All +PREFERENCES_CACHECLEARPROFILES;Clear Profiles +PREFERENCES_CACHECLEARTHUMBS;Clear Thumbnails +PREFERENCES_CACHEFORMAT1;Proprietary (faster and better quality) +PREFERENCES_CACHEFORMAT2;JPEG (smaller disk footprint) +PREFERENCES_CACHEMAXENTRIES;Maximal Number of Cache Entries +PREFERENCES_CACHEOPTS;Cache Options +PREFERENCES_CACHETHUMBFORM;Cache Thumbnail Format +PREFERENCES_CACHETHUMBHEIGHT;Maximal Thumbnail Height +PREFERENCES_CLEARDLG_LINE1;Clearing cache +PREFERENCES_CLEARDLG_LINE2;This may take a few seconds. +PREFERENCES_CLEARDLG_TITLE;Please wait +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_DMETHOD;方式 +PREFERENCES_EDITORCMDLINE;Other command line +PREFERENCES_EXTERNALEDITOR;External editor +PREFERENCES_FALSECOLOR;虛假色彩壓縮步驟 +PREFERENCES_FBROWSEROPTS;檔流覽選項 +PREFERENCES_FILEFORMAT;檔格式 +PREFERENCES_FORIMAGE;用於圖片檔 +PREFERENCES_FORRAW;用於Raw文件 +PREFERENCES_GIMPPATH;GIMP installation directory +PREFERENCES_GTKTHEME;GTK default +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_FILEDLGFILTERANY;任意文件 +PROFILEPANEL_FILEDLGFILTERPP;處理參數配置 +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儲存中... +PROGRESSDLG_LOADING;Loading file... +PROGRESSDLG_PROCESSING;Processing image... +PROGRESSDLG_SAVING;Saving file... +QINFO_ISO;ISO +QINFO_NOEXIF;Exif資料不可用. +SAVEDLG_FILEFORMAT;檔格式 +SAVEDLG_JPEGQUAL;JPEG品質 +SAVEDLG_JPGFILTER;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;隨圖片儲存處理參數 +SAVEDLG_TIFFFILTER;TIFF文件 +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_DEGREE;角度: +TP_COARSETRAF_TOOLTIP_HFLIP;水準翻轉 +TP_COARSETRAF_TOOLTIP_ROTLEFT;左轉 +TP_COARSETRAF_TOOLTIP_ROTRIGHT;右轉 +TP_COARSETRAF_TOOLTIP_VFLIP;豎直翻轉 +TP_COLORBOOST_ACHANNEL;通道 "a" +TP_COLORBOOST_AMOUNT;程度 +TP_COLORBOOST_AVOIDCOLORCLIP;避免色彩溢出 +TP_COLORBOOST_BCHANNEL;通道 "b" +TP_COLORBOOST_CHANNEL;通道 +TP_COLORBOOST_CHSEPARATE;分解 +TP_COLORBOOST_ENABLESATLIMITER;啟用飽和度限制 +TP_COLORBOOST_LABEL;色彩增益 +TP_COLORBOOST_SATLIMIT;飽和度限制 +TP_COLORDENOISE_EDGESENSITIVE;邊緣敏感度 +TP_COLORDENOISE_EDGETOLERANCE;邊緣容差 +TP_COLORDENOISE_LABEL;色彩噪點抑制 +TP_COLORDENOISE_RADIUS;半徑 +TP_COLORSHIFT_BLUEYELLOW;藍-黃 +TP_COLORSHIFT_GREENMAGENTA;綠-洋紅 +TP_COLORSHIFT_LABEL;色彩偏移 +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;比例: +TP_CROP_GTDIAGONALS;對角線法則 +TP_CROP_GTHARMMEANS1;黃金點 1 +TP_CROP_GTHARMMEANS2;黃金點 2 +TP_CROP_GTHARMMEANS3;黃金點 3 +TP_CROP_GTHARMMEANS4;黃金點 4 +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_DETAIL_AMOUNT;Amount +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_FILEDLGFILTERANY;任意文件 +TP_ICM_FILEDLGFILTERICM;ICC配置檔 +TP_ICM_GAMMABEFOREINPUT;Profile applies Gamma +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_LUMACURVE_BLACKLEVEL;黑 +TP_LUMACURVE_BRIGHTNESS;亮度 +TP_LUMACURVE_COMPRHIGHLIGHTS;亮部壓縮 +TP_LUMACURVE_COMPRSHADOWS;暗部壓縮 +TP_LUMACURVE_CONTRAST;對比度 +TP_LUMACURVE_CURVEEDITOR;亮度曲線 +TP_LUMACURVE_LABEL;亮度曲線 +TP_RESIZE_BICUBICSF;雙三次 (柔化) +TP_RESIZE_BICUBICSH;雙三次 (銳化) +TP_RESIZE_BICUBIC;雙三次 +TP_RESIZE_BILINEAR;雙線性 +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_AUTOCROP;自動剪裁 +TP_ROTATE_DEGREE;角度 +TP_ROTATE_FILL;填充 +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_CURVES;Curves +!CURVEEDITOR_CURVE;Curve +!CURVEEDITOR_CUSTOM;Custom +!CURVEEDITOR_DARKS;Darks +!CURVEEDITOR_HIGHLIGHTS;Highlights +!CURVEEDITOR_LIGHTS;Lights +!CURVEEDITOR_MINMAXCPOINTS;Minima/Maxima control points +!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 +!EXIFFILTER_EXPOSURECOMPENSATION;Exposure Compensation (EV) +!EXIFFILTER_FILETYPE;File Type +!EXIFFILTER_METADATAFILTER;Enable Metadata Filters +!EXPORT_BYPASS_ALL;Select / Unselect All +!EXPORT_BYPASS_COLORDENOISE;Bypass Color denoise +!EXPORT_BYPASS_DEFRINGE;Bypass Defringe +!EXPORT_BYPASS_DIRPYRDENOISE;Bypass Noise Reduction +!EXPORT_BYPASS_DIRPYREQUALIZER;Bypass Contrast by Detail Levels +!EXPORT_BYPASS_LUMADENOISE;Bypass Luma denoise +!EXPORT_BYPASS_RAW_ALL_ENHANCE;Bypass Post Demosaic Artifact/Noise Reduction +!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 +!EXPORT_RESIZEMETHOD;Resize 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.\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\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_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_POPUPRANK;Rank +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!FILEBROWSER_QUERYHINT;Type a partial filename to search for or a comma-separated list.\nE.g. 1001,1004,1199 \n\nCtrl-F to focus to the Find text box.\nEnter to commence search.\nEsc to clear.\nShift-Esc to remove focus. +!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.\nShortcut: i\n\nShortcut in Single Editor Tab Mode: Alt-i +!FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show images recently saved.\nShortcut: Alt-7 +!FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show images not recently saved.\nShortcut: Alt-6 +!FILEBROWSER_SHOWUNCOLORHINT;Show images without Color label.\nShortcut: Alt-0 +!FILEBROWSER_UNRANK_TOOLTIP;Unrank\nShortcut: Shift-0 +!FILEBROWSER_USETEMPLATE;Use template: +!GENERAL_AUTO;Automatic +!GENERAL_CLOSE;Close +!GENERAL_FILE;File +!GENERAL_NONE;None +!GENERAL_WARNING;Warning +!HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar\nClick right mouse button on image preview to freeze/unfreeze +!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram +!HISTOGRAM_TOOLTIP_FULL;Toggle full (on) or scaled (off) 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;Lab - Chromaticity +!HISTORY_MSG_96;'a' Curve +!HISTORY_MSG_97;'b' Curve +!HISTORY_MSG_98;Demosaicing Method +!HISTORY_MSG_99;Hot/Dead pixel filter +!HISTORY_MSG_100;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;Resizing applies to +!HISTORY_MSG_111;Lab - Avoid color shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;Lab - Protection +!HISTORY_MSG_114;DCB Iterations +!HISTORY_MSG_115;False Color Suppression +!HISTORY_MSG_116;DCB Enhancement +!HISTORY_MSG_117;Raw Red CA Correction +!HISTORY_MSG_118;Raw Blue CA Correction +!HISTORY_MSG_119;Line Noise Filter +!HISTORY_MSG_120;Green Equilibration +!HISTORY_MSG_121;Raw Auto CA +!HISTORY_MSG_122;Dark Frame Auto Select +!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 Select +!HISTORY_MSG_128;Flat Field Blur Radius +!HISTORY_MSG_129;Flat Field Blur Type +!HISTORY_MSG_130;Auto Distorion +!HISTORY_MSG_131;Noise Reduction Luma +!HISTORY_MSG_132;Noise Reduction 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;Edges Sharpening +!HISTORY_MSG_147;ES - Luminance Only +!HISTORY_MSG_148;Microcontrast +!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_150;Post Demosaic Artifact/Noise Reduction +!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;'CC' curve +!HISTORY_MSG_169;'CH' curve +!HISTORY_MSG_170;Vib - Curve +!HISTORY_MSG_171;'LC' curve +!HISTORY_MSG_172;Lab - 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 tones protection +!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 pixels +!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;'CL' curve +!HISTORY_MSG_247;'LH' curve +!HISTORY_MSG_248;'HH' curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +!MAIN_BUTTON_FULLSCREEN;Fullscreen +!MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the Next image relative to image open in Editor\nShortcut: Shift-F4\n\nTo navigate to the Next image relative to thumbnail selected in File Browser\nShortcut: F4 +!MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the Previous image relative to image open in Editor\nShortcut: Shift-F3 \n\nTo navigate to the Previous image relative to thumbnail selected in File Browser\nShortcut: F3 +!MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronize the File Browser with the Editor to reveal the thumbnail of the currently open image, and clear filters in File Browser \nShortcut: x\n\nAs above, but without clearing filters in File Browser\nShortcut: y\n(Note that thumbnail of the open file 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\ndoesn't exist. Please set a correct path in the Preference window. +!MAIN_MSG_SETPATHFIRST;You have to set a target path first in Preferences\nin order to use this function! +!MAIN_MSG_WRITEFAILED;Failed to write\n\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_METADATA_TOOLTIP;Shortcut: Alt-m +!MAIN_TAB_RAW;Raw +!MAIN_TAB_RAW_TOOLTIP;Shortcut: Alt-r +!MAIN_TAB_TRANSFORM_TOOLTIP;Shortcut: Alt-t +!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 10-30%\n\nPreview is rendered slower with Focus Mask turned on. +!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_NA;B = n/a +!NAVIGATOR_B_VALUE;B = %1 +!NAVIGATOR_G_NA;G = n/a +!NAVIGATOR_G_VALUE;G = %1 +!NAVIGATOR_H_NA;H = n/a +!NAVIGATOR_H_VALUE;H = %1 +!NAVIGATOR_LAB_A_NA;a = n/a +!NAVIGATOR_LAB_A_VALUE;a = %1 +!NAVIGATOR_LAB_B_NA;b = n/a +!NAVIGATOR_LAB_B_VALUE;b = %1 +!NAVIGATOR_LAB_L_NA;L = n/a +!NAVIGATOR_LAB_L_VALUE;L = %1 +!NAVIGATOR_R_NA;R = n/a +!NAVIGATOR_R_VALUE;R = %1 +!NAVIGATOR_S_NA;S = n/a +!NAVIGATOR_S_VALUE;S = %1 +!NAVIGATOR_V_NA;V = n/a +!NAVIGATOR_V_VALUE;V = %1 +!NAVIGATOR_XY_FULL;Width = %1, Height = %2 +!NAVIGATOR_XY_NA;x = n/a, y = n/a +!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;CIE Color Appearance Model 2002 +!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_EVERYTHING;Everything +!PARTIALPASTE_FLATFIELDAUTOSELECT;Flat field auto selection +!PARTIALPASTE_FLATFIELDBLURRADIUS;Flat field blur radius +!PARTIALPASTE_FLATFIELDBLURTYPE;Flat field blur type +!PARTIALPASTE_FLATFIELDFILE;Flat field file +!PARTIALPASTE_GRADIENT;Graduated filter +!PARTIALPASTE_HSVEQUALIZER;HSV equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!PARTIALPASTE_LABCURVE;Lab adjustments +!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_PERSPECTIVE;Perspective +!PARTIALPASTE_PREPROCESS_GREENEQUIL;Green equilibration +!PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Apply hot/dead 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_ALLENHANCE;Post-demosaic artifact/noise reduction +!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 +!PREFERENCES_ADD;Add +!PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!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_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_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 scipts 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_DATEFORMATFRAME;Date Format +!PREFERENCES_DIRDARKFRAMES;Dark frames directory +!PREFERENCES_EDITORLAYOUT;Editor Layout +!PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar (de-select for low resolution display) +!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_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;Output device's Yb luminance (%) +!PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogram in left panel +!PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Show embedded JPEG thumbnail if raw is unedited +!PREFERENCES_LANGAUTODETECT;Use OS language setting +!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_MULTITABDUALMON;Multiple Editor Tabs Mode (if available on second monitor) +!PREFERENCES_MULTITAB;Multiple Editor Tabs Mode +!PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails +!PREFERENCES_OVERWRITEOUTPUTFILE;Overwrite existing output files +!PREFERENCES_PANFACTORFRAME;Pan Rate Amplification +!PREFERENCES_PANFACTORLABEL;Factor +!PREFERENCES_PROPERTY;Property +!PREFERENCES_RGBDTL_LABEL;Max number of threads for Noise Reduction +!PREFERENCES_RGBDTL_TOOLTIP;Noise Reduction requires a baseline of about 128MB RAM for a 10MPix image or 512MB for a 40MPix image, and additionally 128MB RAM per thread. The more threads run in parallel, the faster the computation. Leave the setting at "0" to automatically use as many threads as possible. +!PREFERENCES_SELECTFONT;Select font +!PREFERENCES_SET;Set +!PREFERENCES_SHOWEXPOSURECOMPENSATION;Append exposure compensation +!PREFERENCES_SHOWPROFILESELECTOR;Show processing profile selector +!PREFERENCES_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs +!PREFERENCES_SINGLETAB;Single Editor Tab Mode +!PREFERENCES_SLIMUI;Slim interface +!PREFERENCES_SND_BATCHQUEUEDONE;Queue processing done +!PREFERENCES_SND_HELP;Either enter filepath or nothing (for no sound).\nOn Windows use "SystemDefault", "SystemAsterisk" etc. for system sounds.\nOn Linux use "complete", "window-attention" etc. for system sounds. +!PREFERENCES_SND_LNGEDITPROCDONE;Editor processing done +!PREFERENCES_SND_TRESHOLDSECS;after secs +!PREFERENCES_SQUAREDETAILWINDOW;Square detail window (faster) +!PREFERENCES_TAB_PERFORMANCE;Performance +!PREFERENCES_TAB_SOUND;Sounds +!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_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_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing channel-mixer +!TP_BWMIX_BLUE;Blue +!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;Modify luminance in function of hue\nPay attention to extreme values that may cause artifacts +!TP_BWMIX_CYAN;Cyan +!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 simulate shots taken with a colored filter placed in front of the lens. Colored filters reduce transmission of specific range of colors and correspondingly affect their lightness. E.g. a Red filter darkens Blue skies. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_BLUE;Blue Channel +!TP_BWMIX_GAM_GREEN;Green Channel +!TP_BWMIX_GAM_RED;Red Channel +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each channel RGB +!TP_BWMIX_GREEN;Green +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MAGENTA;Magenta +!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 (filter, channel-mixer) to default +!TP_BWMIX_ORANGE;Orange +!TP_BWMIX_PURPLE;Purple +!TP_BWMIX_RED;Red +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all of the mixer options\nTotal displays the sum of RGB values actually applied:\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 (films, landscape, ...) or manual settings of channel-mixer +!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;Channel-Mixer absolute RGB +!TP_BWMIX_SET_RGBREL;Channel-Mixer relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Channel-Mixer absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Channel-Mixer 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_BWMIX_YELLOW;Yellow +!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) RT 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.\n 0=no effect 1=median 2=gaussian.\n\nThese artifacts are due to limitations of CIECAM02. Alternatively, adjust the image to avoid very dark shadows. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from Lab and RGB brightness +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from Lab and RGB colorfulness +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from Lab and RGB saturation +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from Lab 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 Lab and RGB contrast +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from Lab and RGB contrast +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L (Lab) 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 (Lab) 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 Lab values before CIECAM02 adjustments +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RT 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 (Lab) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in Lab 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 Lab and RGB lightness +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model\n\nWB [RT] + [output]:\nRT's white balance is used for the scene, CIECAM02 is set to D50, the output device's white balance is set in Preferences > Color Management\n\nWB [RT+CAT02] + [output]:\nRT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences +!TP_COLORAPP_RSTPRO;Red & skin tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin tones protection (sliders and curves) +!TP_COLORAPP_SHARPCIE;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe with Q/C +!TP_COLORAPP_SHARPCIE_TOOLTIP;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe will use CIECAM02 if enabled. +!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;Change tones and colors to take into account the viewing conditions of the output device\n\nAverage:\nAverage light environment (standard)\nThe image will not change\n\nDim:\nDim environment (TV)\nThe image will become slighty dark\n\nDark:\nDark environment (projector)\nThe image will become more dark\n\nExtremly Dark:\nExtremly dark environment (cutsheet)\nThe image will become very dark +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if source 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 Lab 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_CROP_GTEPASSPORT;Biometric Passport +!TP_CROP_GTFRAME;Frame +!TP_CROP_GTGRID;Grid +!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_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_CHROMA;Chrominance - Master +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on gamma of the input color profile. Gamma of sRGB is assumed, thus if input image is in color profile of a different gamma, luminance noise reduction will vary. +!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_LAB;Lab +!TP_DIRPYRDENOISE_LDETAIL;Luminance Detail +!TP_DIRPYRDENOISE_LUMA;Luminance +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or Lab methods can be used.\n\nFor non-raw images Lab method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_PERF;RGB mode (raw images) +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGB;RGB +!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_THRESHOLD;Threshold +!TP_DISTORTION_AUTO;Auto Distortion Correction +!TP_DISTORTION_AUTO_TIP;(Exprimental) Correct lens distortion automatically for some cameras (Micro 4/3, some compact digital cameras, etc.) +!TP_EPD_EDGESTOPPING;Edge Stopping +!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 via Lab mode (standard) and CIECAM02 mode.\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_EXPOSCORR_LABEL;Raw White & Black Points +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggle execution of auto levels to automatically set parameter values based on image analysis\nEnable Highlight Reconstruction if necessary +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in auto level's 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 following section of the manual to learn how to achieve the best results with double curves:\nThe Toolbox > Exposure Tab > Exposure Panel > Tone Curve +!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_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!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_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 effect of this tool or some of its sub-component is only visible at 1:1 preview scale. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Rotation anchor point X: -100=left edge, 0=center, +100=right edge +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Rotation anchor point Y: -100=top edge, 0=center, +100=bottom edge +!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 automatic exposure +!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 blown 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 simple color matrix by dcraw, enhanced RawTherapee version (whichever is available based on camera model) or embedded in 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. Use only in special cases. +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. Result can be used for calibration purposes, 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;Lab 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;Can be used with the Chromaticity slider and the CC curve. +!TP_LENSGEOM_AUTOCROP;Auto Crop +!TP_LENSGEOM_FILL;Auto fill +!TP_LENSGEOM_LABEL;Lens / Geometry +!TP_LENSPROFILE_FILEDLGFILTERLCP;Lens correction files +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;CA Correction +!TP_LENSPROFILE_USEDIST;Distortion correction +!TP_LENSPROFILE_USEVIGN;Vignetting correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset 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: 0=corners only, 50=halfway to center, 100=to center +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness: 0=rectangle, 50=fitted ellipse, 100=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. Higher = more, lower = less. +!TP_PREPROCESS_GREENEQUIL;Green Equilibration +!TP_PREPROCESS_HOTDEADPIXFILT;Hot/Dead pixel filter +!TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Try to suppress hot and dead 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_BLACKONE;Black Level: Red +!TP_RAWEXPOS_BLACKS;Black Levels +!TP_RAWEXPOS_BLACKTHREE;Black Level: Green 2 +!TP_RAWEXPOS_BLACKTWO;Black Level: Blue +!TP_RAWEXPOS_BLACKZERO;Black Level: Green 1 (lead) +!TP_RAWEXPOS_LINEAR;White Point Correction +!TP_RAWEXPOS_PRESER;Highlight Preservation +!TP_RAWEXPOS_TWOGREEN;Link greens +!TP_RAW_ALLENHANCE;Post-Demosaic Artifact/Noise Reduction +!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 +!TP_RAW_FALSECOLOR;False Color Suppression Steps +!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_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 used 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_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_ZOOMFITSCREEN;Fit 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..62eeb2e5b --- /dev/null +++ b/rtdata/languages/Czech @@ -0,0 +1,1421 @@ +#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 + +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_FILEDLGFILTERANY;Jakékoliv soubory +CURVEEDITOR_FILEDLGFILTERCURVE;Soubory křivek +CURVEEDITOR_HIGHLIGHTS;Světla +CURVEEDITOR_LIGHTS;Světlé +CURVEEDITOR_LINEAR;Lineární +CURVEEDITOR_LOADDLGLABEL;Načíst křivku... +CURVEEDITOR_MINMAXCPOINTS;Min/Max kontrolní body +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 +EDITWINDOW_TITLE;Editace obrázku +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/Opravit š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_COLORDENOISE;Vynechat odstranění barevného šumu +EXPORT_BYPASS_DEFRINGE;Vynechat odstranění lemu +EXPORT_BYPASS_DIRPYRDENOISE;Vynechat redukci šumu +EXPORT_BYPASS_DIRPYREQUALIZER;Vynechat kontrast dle detailu úrovní +EXPORT_BYPASS_LUMADENOISE;Vynechat redukci jasového šumu +EXPORT_BYPASS_RAW_ALL_ENHANCE;Vynechat redukci artefaktů a šumu po demozajkování +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í +EXPORT_RESIZEMETHOD;Metoda změny rozměru +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í.\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\n\nZkratky pro cesty:\n ~ - domácí složka uživatele\n ! - složka s obrázky uživatele +FILEBROWSER_CACHECLEARFROMFULL;Vymazat z cache - úplně +FILEBROWSER_CACHECLEARFROMPARTIAL;Vymazat z cache - částečně +FILEBROWSER_CACHE;Cache +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_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_POPUPOPEN;Otevřít +FILEBROWSER_POPUPPROCESSFAST;Vložit do fronty (Rychlý export) +FILEBROWSER_POPUPPROCESS;Vložit do fronty +FILEBROWSER_POPUPPROFILEOPERATIONS;Operace profilů zpracování +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 část jména hledaného souboru nebo čárkami oddělený seznam.\nNapříklad: 1001,1004,1199 \n\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.\nZkratka: i\n\nZkratka v módu jedné karty editoru: Alt-i +FILEBROWSER_SHOWRANK1HINT;Ukázat obrázky hodnocené 1 hvězdičkou.\nZkratka: 1 +FILEBROWSER_SHOWRANK2HINT;Ukázat obrázky hodnocené 2 hvězdičkami.\nZkratka: 2 +FILEBROWSER_SHOWRANK3HINT;Ukázat obrázky hodnocené 3 hvězdičkami.\nZkratka: 3 +FILEBROWSER_SHOWRANK4HINT;Ukázat obrázky hodnocené 4 hvězdičkami.\nZkratka: 4 +FILEBROWSER_SHOWRANK5HINT;Ukázat obrázky hodnocené 5 hvězdičkami.\nZkratka: 5 +FILEBROWSER_SHOWRECENTLYSAVEDHINT;Ukázat naposledy uložené obrázky.\nZkratka: Alt-7 +FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Ukázat naposledy neuložené obrázky.\nZkratka: Alt-6 +FILEBROWSER_SHOWTRASHHINT;Ukázat obsah koše.\nZkratka: 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_USETEMPLATE;Použít šablonu: +FILEBROWSER_ZOOMINHINT;Zvětšit velikosti náhledů.\nZkratka: +\n\nZkratka v módu jedné karty editoru: Alt-+ +FILEBROWSER_ZOOMOUTHINT;Zmenšit velikosti náhledů.\nZkratka: -\n\nZkratka v módu jedné karty editoru: Alt-- +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;Lab - Světlost +HISTORY_MSG_15;Lab - Kontrast +HISTORY_MSG_16;Jas Černá +HISTORY_MSG_17;Jas Komprese světel +HISTORY_MSG_18;Jas Komprese stínů +HISTORY_MSG_19;'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;Míra změny rozměrů +HISTORY_MSG_75;Metoda změny rozměru +HISTORY_MSG_76;Exif Metadata +HISTORY_MSG_77;IPTC Metadata +HISTORY_MSG_78;Data pro změnu rozměrů +HISTORY_MSG_79;Změna šířky +HISTORY_MSG_80;Změna délky +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;Red. impulz. š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;Lab - Barevnost +HISTORY_MSG_96;'a' křivka +HISTORY_MSG_97;'b' křivka +HISTORY_MSG_98;Metoda demozajkování +HISTORY_MSG_99;Filtr vypálených/mrtvých pixelů +HISTORY_MSG_100;Sytost +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ýřezu +HISTORY_MSG_110;Změna rozměrů aplikována na +HISTORY_MSG_111;Lab - Zabránit posunu barev +HISTORY_MSG_112;--nepoužito-- +HISTORY_MSG_113;Lab - Ochrana +HISTORY_MSG_114;Průchody DCB +HISTORY_MSG_115;Potlačování chybných barev +HISTORY_MSG_116;DCB vylepšení +HISTORY_MSG_117;Raw - Korekce červené CA +HISTORY_MSG_118;Raw - Korekce modré CA +HISTORY_MSG_119;Filtrovat linkové rušení +HISTORY_MSG_120;Vyrovnání zelené +HISTORY_MSG_121;Raw - Automatická CA +HISTORY_MSG_122;Tmavý snímky - Aut. výběr +HISTORY_MSG_123;Soubor tmavého snímku +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á oprava zkreslení objektivu +HISTORY_MSG_131;Redukce jasového šumu +HISTORY_MSG_132;Redukce barevného šumu +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 3x3 +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;'CC' křivka +HISTORY_MSG_169;'CH' křivka +HISTORY_MSG_170;Živost - Křivka +HISTORY_MSG_171;'LC' křivka +HISTORY_MSG_172;Lab - Omezit 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 - Ochr. č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 Č,Z +HISTORY_MSG_202;Redukce šumu - Barevnost M, Ž +HISTORY_MSG_203;Redukce šumu - Metoda +HISTORY_MSG_204;Kroky vylepšení LMMSE +HISTORY_MSG_205;CAM02 - Vypálené/špatné pixely +HISTORY_MSG_206;CAT02 - Automatická svítivost scény +HISTORY_MSG_207;Odstr. lemu - Křivka odstínu +HISTORY_MSG_208;VB - 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;'CL' křivka +HISTORY_MSG_247;'LH' křivka +HISTORY_MSG_248;'HH' křivka +HISTORY_MSG_249;KdDÚ - Práh +HISTORY_MSG_250;Redukce šumu - Vylepšení +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ů \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ů \nZkratka: F3 +MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronizovat prohlížeč souborů s editorem pro zobrazení náhleduaktuá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\n"%1"\n\nUjistětě 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_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_TAGGING;Štítky +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í (10-30%)\n\nPokud je maska zaostření zapnuta je náhled generován pomaleji. +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_NA;B = n/a +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_LAB_A_NA;a = n/a +NAVIGATOR_LAB_A_VALUE;a = %1 +NAVIGATOR_LAB_B_NA;b = n/a +NAVIGATOR_LAB_B_VALUE;b = %1 +NAVIGATOR_LAB_L_NA;L = n/a +NAVIGATOR_LAB_L_VALUE;L = %1 +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_V_VALUE;V = %1 +NAVIGATOR_XY_FULL;Šířka = %1, Výška = %2 +NAVIGATOR_XY_NA;x = n/a, y = n/a +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;Rotace o 90° / překlopení +PARTIALPASTE_COLORAPP;CIE Color Appearance Model 2002 +PARTIALPASTE_COLORGROUP;Nastavení barev +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_EVERYTHING;Vše +PARTIALPASTE_EXIFCHANGES;Změny Exif dat +PARTIALPASTE_EXPOSURE;Expozice +PARTIALPASTE_FLATFIELDAUTOSELECT;Flat field automatický výběr +PARTIALPASTE_FLATFIELDBLURRADIUS;Flat field poloměr rozostření +PARTIALPASTE_FLATFIELDBLURTYPE;Flat field typ rozostření +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 info +PARTIALPASTE_LABCURVE;Úprava LAB křivek +PARTIALPASTE_LENSGROUP;Nastavení objektivu +PARTIALPASTE_LENSPROFILE;Korekční profil objektivu +PARTIALPASTE_METAICMGROUP;Nastavení metadat a správy barev +PARTIALPASTE_PCVIGNETTE;Viněta +PARTIALPASTE_PERSPECTIVE;Perspektiva +PARTIALPASTE_PREPROCESS_GREENEQUIL;Vyrovnání zelené +PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Aplikovat filtr na vypálené/mrtvé body +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_ALLENHANCE;Redukce artefaktů/šumu po demozajkování +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_AUTOMONPROFILE;Použít barevný profil hlavního monitoru z operačního systému +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_BLINKCLIPPED;Blikání v oříznutých oblastech +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 cache +PREFERENCES_CACHEOPTS;Vlastnosti cache +PREFERENCES_CACHETHUMBHEIGHT;Maximální výška náhledu +PREFERENCES_CIEART;CIECAM02 optimalizace +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_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ů skriptem vyžadovaných 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_DATEFORMATFRAME;Formát data +PREFERENCES_DATEFORMATHINT;Lze použít následující formátovací řetězce:\n%y : rok (year)\n%m : měsíc (month)\n%d : den (day)\n\nNapříklad český formát data:\n%d. %m. %y +PREFERENCES_DATEFORMAT;Formát data +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_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_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_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_GREY;Yb svítivost výstupního zařízení (%) +PREFERENCES_GTKTHEME;GTK výchozí +PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogram v levém panelu +PREFERENCES_HLTHRESHOLD;Práh oříznutých světel +PREFERENCES_ICCDIR;Složka obsahující barevné profily +PREFERENCES_IMPROCPARAMS;Výchozí parametry zpracování obrázku +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 jazykové nastavení OS +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_MONITORICC;Barevný profil monitoru +PREFERENCES_MULTITABDUALMON;Mód více karet editoru (pokud je dostupný druhý monitor) +PREFERENCES_MULTITAB;Mód více karet editoru +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řepsat jména souborů v náhledech +PREFERENCES_OVERWRITEOUTPUTFILE;Přepsat existující soubory +PREFERENCES_PANFACTORFRAME;Zrychlení posunu výřezu +PREFERENCES_PANFACTORLABEL;Násobitel +PREFERENCES_PARSEDEXTADDHINT;Vložte příponu a stiskněte toto tlačítko pro přidání do seznamu +PREFERENCES_PARSEDEXTADD;Přidej příponu +PREFERENCES_PARSEDEXTDELHINT;Vymazat označenou příponu ze seznamu +PREFERENCES_PARSEDEXT;Zachytávané přípony +PREFERENCES_PROFILEHANDLING;Řízení profilů zpracování +PREFERENCES_PROFILELOADPR;Priorita nahrávání profilů zpracování +PREFERENCES_PROFILEPRCACHE;Profil v cache +PREFERENCES_PROFILEPRFILE;Profil uložený se zdrojovým souborem +PREFERENCES_PROFILESAVECACHE;Ukládat parametry zpracování do cache +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 +PREFERENCES_RGBDTL_TOOLTIP;Redukce šumu potřebuje v základu 128MB RAM u 10MPix obrázku nebo 512MB pro 40MPix obrázek plus dalších 128MB RAM pro každé vlákno. Více paralelních vláken zvyšuje spotřebu paměti. Při nastavení na nulu je automaticky použit maximální možný počet vláken. +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_SHOWPROFILESELECTOR;Zobrazit výběr profilu zpracování +PREFERENCES_SHTHRESHOLD;Práh oříznutých stínů +PREFERENCES_SINGLETABVERTAB;Mód jedné karty editoru, svislé karty +PREFERENCES_SINGLETAB;Mód jedné karty editoru +PREFERENCES_SLIMUI;Štíhlé rozhraní +PREFERENCES_SND_BATCHQUEUEDONE;Zpracování fronty dokončeno +PREFERENCES_SND_HELP;Vložte cestu k souboru nebo ponechte prázdné (bez zvuku). \nVe Windows zadejte "SystemDefault", "SystemAsterisk", atd. pro použití systémových zvuků. \nNa Linuxu pro systémové zvuky použijte "complete", "window-attention" a další. +PREFERENCES_SND_LNGEDITPROCDONE;Zpracování v editoru dokončeno +PREFERENCES_SND_TRESHOLDSECS;po sekundách +PREFERENCES_SQUAREDETAILWINDOW;Čtvercové okno detailu (rychlejší) +PREFERENCES_STARTUPIMDIR;Složka obrázků při spuště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 +PREFERENCES_TAB_SOUND;Zvuky +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_WORKFLOW;Rozvržení +PROFILEPANEL_COPYPPASTE;Parametry pro kopírování +PROFILEPANEL_FILEDLGFILTERANY;Jakékoliv soubory +PROFILEPANEL_FILEDLGFILTERPP;Profily zpracová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_JPGFILTER;Soubory 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_TIFFFILTER;Soubory TIFF +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_AUTOCH;Automaticky +TP_BWMIX_AUTOCH_TIP;Spočítá optimální hodnoty pro michání kanálů +TP_BWMIX_BLUE;Modrá +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\nUvědomte si, že extrémní hodnoty mohou způsobovat artefakty. +TP_BWMIX_CYAN;Tyrkysová +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;Nic +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_BLUE;Modrý kanál +TP_BWMIX_GAM_GREEN;Zelený kanál +TP_BWMIX_GAM_RED;Červený kanál +TP_BWMIX_GAM_TOOLTIP;Gama korekce pro každý R, G, B kanál +TP_BWMIX_GREEN;Zelená +TP_BWMIX_LABEL;Černobílá +TP_BWMIX_MAGENTA;Purpurová +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_ORANGE;Oranžová +TP_BWMIX_PURPLE;Nachová +TP_BWMIX_RED;Červená +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;Míchání kanálů - úplné RGB +TP_BWMIX_SET_RGBREL;Míchání kanálů - relativní RGB +TP_BWMIX_SET_ROYGCBPMABS;Míchání kanálů - úplné ROYGCBPM +TP_BWMIX_SET_ROYGCBPMREL;Míchání kanálů - 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_BWMIX_YELLOW;Žlutá +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.\nZkratka: [\n\nZkratka v módu jedné karty editoru: Alt-[ +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Otočit doprava.\nZkratka: ]\n\nZkratka v módu jedné karty editoru: Alt-] +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), Rawtherapee vypočítá optimální hodnotu z Exif dat.\nZakažte, pokud si přejete zadat hodnotu ručně. +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ů.\n 0=bez efektu 1=medián 2=gaussový.\n\nTyto artefakty vznikají díky omezením CIECAM02. Popřípadě obrázek zesvětlete tak, aby jste se vyhnuli velmi tmavým stínům. +TP_COLORAPP_BRIGHT;Jas (O) +TP_COLORAPP_BRIGHT_TOOLTIP;Jas v CIECAM02 bere v potaz svítivost bílé a rozdíly jasů mezi Lab 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 Lab a RGB +TP_COLORAPP_CHROMA_S;Sytost (S) +TP_COLORAPP_CHROMA_S_TOOLTIP;Nasycení se v CIECAM02 liší od nasycení Lab a RGB +TP_COLORAPP_CHROMA_TOOLTIP;Barevnost se v CIECAM02 liší od barevnosti Lab 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 Lab a RGB +TP_COLORAPP_CONTRAST_TOOLTIP;Kontrast pro posuvník J se v CIECAM02 liší od kontrastu Lab a RGB +TP_COLORAPP_CURVEEDITOR1;Tónová křivka 1 +TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Zobrazuje histogram L (Lab) 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 (Lab) 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 Lab 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 (Lab) +TP_COLORAPP_GAMUT_TOOLTIP;Povolí kontrolu palety v Lab režimu +TP_COLORAPP_HUE;Odstín (h) +TP_COLORAPP_HUE_TOOLTIP;Odstín (h) - úhel mezi 0° a 360° +TP_COLORAPP_LABEL;CIE Color Appearance Model 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 Lab a RGB +TP_COLORAPP_MODEL;VB - Model +TP_COLORAPP_MODEL_TOOLTIP;Model bílého bodu\n\nWB [RT] + [výstup]:\npro scénu je použito vyvážení bíle Ravtherapee , CIECAM02 je nastaven na D50, \nvyvážení bílé výstupního zařízení je nastaveno ve Volby > Správa barev\n\nWB [RT+CAT02] + [výstup]:\nCAT02 používá Rawtherapee nastavení vyvážení bílé a vyvážení bílé výstupního zařízení je nastaveno ve Volbách +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;Doostření, kontrast dle úrovní, Mikrokontrast a odstranění lemu s Q/C +TP_COLORAPP_SHARPCIE_TOOLTIP;Pokud je povolen CIECAM02, bude je doostření, kontrast dle úrovní, Mikrokontrast a odstranění lemu používat. +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é:\nPrůměrné osvětlení prostředí (standardní)\nObrázek nebude změněn\n\nTlumené:\nTlumené prostředí (TV)\nObrázek bude mírně ztmaven\n\nTmavé:\nTmavé prostředí (projektor)\nObrázek bude více tmavý\n\nVelmi tmavé:\nVelmi tmavé prostředí (cutsheet)\nObrá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 Lab.\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_CROP_FIXRATIO;Pevný 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_GTHARMMEANS1;Zlatý řez 1 +TP_CROP_GTHARMMEANS2;Zlatý řez 2 +TP_CROP_GTHARMMEANS3;Zlatý řez 3 +TP_CROP_GTHARMMEANS4;Zlatý řez 4 +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_BLUE;Barevnost - Modrá a žlutá +TP_DIRPYRDENOISE_CHROMA;Barevnost - Hlavní +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_LAB;Lab +TP_DIRPYRDENOISE_LDETAIL;Jas detailů +TP_DIRPYRDENOISE_LUMA;Jas +TP_DIRPYRDENOISE_METHOD;Metoda +TP_DIRPYRDENOISE_METHOD_TOOLTIP;Pro Raw obrázky může být použita jak RGB tak i Lab metoda.\n\nPro ostatní obrázky bude vždy použita metoda Lab bez ohledu na výběr. +TP_DIRPYRDENOISE_PERF;RGB režim (raw obrázky) +TP_DIRPYRDENOISE_RED;Barevnost - Červená a zelená +TP_DIRPYRDENOISE_RGB;RGB +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_THRESHOLD;Práh +TP_DISTORTION_AMOUNT;Míra +TP_DISTORTION_AUTO;Automatická korekce zkreslení +TP_DISTORTION_AUTO_TIP;(Experimentální) 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;Míra zachování hran +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_EXPOSCORR_LABEL;Raw bílý a černý bod +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 do následující sekce návodu pro více informací o tom jak získat co nejlepší výsledek při využití dvou křivek:\nThe Toolbox > Exposure Tab > Exposure Panel > Tone Curve +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_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_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 nebo některých jeho komponent 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;Bod otáčení X: -100=levá hrana, 0=střed, +100=pravá hrana +TP_GRADIENT_CENTER_Y;Střed Y +TP_GRADIENT_CENTER_Y_TOOLTIP;Bod otáčení Y: -100=horní hrana, 0=střed, +100=spodní hrana +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_FILEDLGFILTERANY;Jakékoliv soubory +TP_ICM_FILEDLGFILTERICM;Barevné profily +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. Použ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\na 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;Lab ú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;Může být použito 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_FILEDLGFILTERLCP;Soubory korekcí objektivu +TP_LENSPROFILE_LABEL;Korekční profil objektivu +TP_LENSPROFILE_USECA;Úprava chromatické vady +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: 0 = pouze rohy, 50 = napůl do středu, 100 = do středu +TP_PCVIGNETTE_LABEL;Viněta +TP_PCVIGNETTE_ROUNDNESS;Zaoblení +TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Zaoblení: 0 = čtverec, 50 = elipsa, 100 = 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. Vyšší = více, nižší = méně. +TP_PREPROCESS_GREENEQUIL;Vyrovnání zelené +TP_PREPROCESS_HOTDEADPIXFILT;Filtr vypálených/mrtvých pixelů +TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Zkusí potlačit vypálené a mrtvé pixely +TP_PREPROCESS_LABEL;Předzpracování +TP_PREPROCESS_LINEDENOISE;Filtrovat linkové rušení +TP_PREPROCESS_NO_FOUND;Nic nenalezeno +TP_RAWCACORR_AUTO;Aplikovat automatickou korekci chromatické aberace +TP_RAWCACORR_CABLUE;Modrá +TP_RAWCACORR_CARED;Červená +TP_RAWEXPOS_BLACKONE;Úroveň černé: Červená +TP_RAWEXPOS_BLACKS;Úrovně černé +TP_RAWEXPOS_BLACKTHREE;Úroveň černé: Zelená 2 +TP_RAWEXPOS_BLACKTWO;Úroveň černé: Modrá +TP_RAWEXPOS_BLACKZERO;Úroveň černé: Zelená 1 (řídící) +TP_RAWEXPOS_LINEAR;Korekce bílého bodu +TP_RAWEXPOS_PRESER;Zachování světel +TP_RAWEXPOS_TWOGREEN;Spojit zelené +TP_RAW_ALLENHANCE;Redukce artefaktů/šumu po demozajkování +TP_RAW_DCBENHANCE;DCB vylepšení +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 +TP_RAW_FALSECOLOR;Počet kroků potlačování chybných barev +TP_RAW_LABEL;Demozajkování +TP_RAW_LMMSEITERATIONS;Kroky vylepš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_RESIZE_APPLIESTO;Aplikovat na: +TP_RESIZE_BICUBICSF;Bikubická (Měkčí) +TP_RESIZE_BICUBICSH;Bikubická (Ostřejší) +TP_RESIZE_BICUBIC;Bikubická +TP_RESIZE_BILINEAR;Bilineární +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: +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;Š: +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;Režim svítivosti umožňuje změnu světlosti obrázku bez změny jeho barev pomocí změny podílu jednotlivých barevných RGB kanálů. +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;Tolerance okrajům +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 3x3 namísto 5x5 +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_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: - + diff --git a/rtdata/languages/Dansk b/rtdata/languages/Dansk new file mode 100644 index 000000000..991e1c6ae --- /dev/null +++ b/rtdata/languages/Dansk @@ -0,0 +1,1441 @@ +#01 2009-06-27 krengbo + +ADJUSTER_RESET_TO_DEFAULT;Nulstil til standard +CURVEEDITOR_FILEDLGFILTERANY;Alle filer +CURVEEDITOR_FILEDLGFILTERCURVE;Kurve-filer +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 +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_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_SAVEAS;Som... +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_TAGGING;Tagging +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_LUMACURVE;Kurve +PARTIALPASTE_METAICMGROUP;Metadata-/ICM-indstillinger +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_BLINKCLIPPED;Blink i udbrændte områder +PREFERENCES_CACHECLEARALL;Ryd alt +PREFERENCES_CACHECLEARPROFILES;Ryd profiler +PREFERENCES_CACHECLEARTHUMBS;Ryd miniaturer +PREFERENCES_CACHEFORMAT1;Proprietær (hurtigere og bedre kvalitet) +PREFERENCES_CACHEFORMAT2;JPEG (fylder mindre på disken) +PREFERENCES_CACHEMAXENTRIES;Maksimalt antal indskrivninger i cache +PREFERENCES_CACHEOPTS;Cache-indstillinger +PREFERENCES_CACHETHUMBFORM;Cache miniature-format +PREFERENCES_CACHETHUMBHEIGHT;Maksimal miniaturehøjde +PREFERENCES_CLEARDLG_LINE1;Rydder cache +PREFERENCES_CLEARDLG_LINE2;Dette kan tage nogle sekunder. +PREFERENCES_CLEARDLG_TITLE;Vent venligst +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_GTKTHEME;GTK-standard +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_FILEDLGFILTERANY;Alle filer +PROFILEPANEL_FILEDLGFILTERPP;Efterbehandlingsprofiler +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... +PROGRESSDLG_LOADING;Indlæser fil... +PROGRESSDLG_PROCESSING;bearbejder billede... +PROGRESSDLG_SAVING;Gemmer fil... +QINFO_ISO;ISO +QINFO_NOEXIF;Exif-data ikke tilgængelig. +SAVEDLG_FILEFORMAT;Filformat +SAVEDLG_JPEGQUAL;JPEG-kvalitet +SAVEDLG_JPGFILTER;JPEG-filer +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 +SAVEDLG_TIFFFILTER;TIFF-filer +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_DEGREE;grader: +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_COLORBOOST_ACHANNEL;Kanal "a" +TP_COLORBOOST_AMOUNT;Mængde +TP_COLORBOOST_AVOIDCOLORCLIP;Undgå farveklipning +TP_COLORBOOST_BCHANNEL;Kanal "b" +TP_COLORBOOST_CHANNEL;Kanal +TP_COLORBOOST_CHSEPARATE;Separér +TP_COLORBOOST_ENABLESATLIMITER;Anvend mætningsbegrænser +TP_COLORBOOST_LABEL;Forstærk farver +TP_COLORBOOST_SATLIMIT;Mætningsbegrænsning +TP_COLORDENOISE_EDGESENSITIVE;Kantfølsomhed +TP_COLORDENOISE_EDGETOLERANCE;kanttolerance +TP_COLORDENOISE_LABEL;Farvestøj +TP_COLORDENOISE_RADIUS;Radius +TP_COLORSHIFT_BLUEYELLOW;Blå-Gul +TP_COLORSHIFT_GREENMAGENTA;Grøn-Magenta +TP_COLORSHIFT_LABEL;Farveskift +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;Fasthold sideforhold: +TP_CROP_GTDIAGONALS;Reglen om diagonaler +TP_CROP_GTHARMMEANS1;Harmonisk metode 1 +TP_CROP_GTHARMMEANS2;Harmonisk metode 2 +TP_CROP_GTHARMMEANS3;Harmonisk metode 3 +TP_CROP_GTHARMMEANS4;Harmonisk metode 4 +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_FILEDLGFILTERANY;alle filer +TP_ICM_FILEDLGFILTERICM;ICC-profil-filer +TP_ICM_GAMMABEFOREINPUT;Profil anvender gamma +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_LUMACURVE_BLACKLEVEL;Sort +TP_LUMACURVE_BRIGHTNESS;Lysstyrke +TP_LUMACURVE_COMPRHIGHLIGHTS;Komprimering af højlys +TP_LUMACURVE_COMPRSHADOWS;Komprimering af skygger +TP_LUMACURVE_CONTRAST;Skygger +TP_LUMACURVE_CURVEEDITOR;Kurve for lysforhold +TP_LUMACURVE_LABEL;Kurve for lysforhold +TP_RAW_DMETHOD;Metode +TP_RAW_FALSECOLOR;Antal trin til undertrykkelse af forkert farve +TP_RESIZE_BICUBICSF;Bikubisk (blødere) +TP_RESIZE_BICUBICSH;Bikubisk (skarpere) +TP_RESIZE_BICUBIC;Bikubisk +TP_RESIZE_BILINEAR;Bilineær +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_AUTOCROP;Autobeskæring +TP_ROTATE_DEGREE;Grader +TP_ROTATE_FILL;Udfyld +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_CURVES;Curves +!CURVEEDITOR_CURVE;Curve +!CURVEEDITOR_CUSTOM;Custom +!CURVEEDITOR_DARKS;Darks +!CURVEEDITOR_HIGHLIGHTS;Highlights +!CURVEEDITOR_LIGHTS;Lights +!CURVEEDITOR_MINMAXCPOINTS;Minima/Maxima control points +!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 +!EXIFFILTER_EXPOSURECOMPENSATION;Exposure Compensation (EV) +!EXIFFILTER_FILETYPE;File Type +!EXIFFILTER_METADATAFILTER;Enable Metadata Filters +!EXPORT_BYPASS_ALL;Select / Unselect All +!EXPORT_BYPASS_COLORDENOISE;Bypass Color denoise +!EXPORT_BYPASS_DEFRINGE;Bypass Defringe +!EXPORT_BYPASS_DIRPYRDENOISE;Bypass Noise Reduction +!EXPORT_BYPASS_DIRPYREQUALIZER;Bypass Contrast by Detail Levels +!EXPORT_BYPASS_LUMADENOISE;Bypass Luma denoise +!EXPORT_BYPASS_RAW_ALL_ENHANCE;Bypass Post Demosaic Artifact/Noise Reduction +!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 +!EXPORT_RESIZEMETHOD;Resize 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.\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\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_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_POPUPRANK;Rank +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!FILEBROWSER_QUERYHINT;Type a partial filename to search for or a comma-separated list.\nE.g. 1001,1004,1199 \n\nCtrl-F to focus to the Find text box.\nEnter to commence search.\nEsc to clear.\nShift-Esc to remove focus. +!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.\nShortcut: i\n\nShortcut in Single Editor Tab Mode: Alt-i +!FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show images recently saved.\nShortcut: Alt-7 +!FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show images not recently saved.\nShortcut: Alt-6 +!FILEBROWSER_SHOWUNCOLORHINT;Show images without Color label.\nShortcut: Alt-0 +!FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +!FILEBROWSER_UNRANK_TOOLTIP;Unrank\nShortcut: Shift-0 +!FILEBROWSER_USETEMPLATE;Use template: +!GENERAL_AFTER;After +!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\nClick right mouse button on image preview to freeze/unfreeze +!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram +!HISTOGRAM_TOOLTIP_FULL;Toggle full (on) or scaled (off) 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;Lab - Chromaticity +!HISTORY_MSG_96;'a' Curve +!HISTORY_MSG_97;'b' Curve +!HISTORY_MSG_98;Demosaicing Method +!HISTORY_MSG_99;Hot/Dead pixel filter +!HISTORY_MSG_100;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;Resizing applies to +!HISTORY_MSG_111;Lab - Avoid color shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;Lab - Protection +!HISTORY_MSG_114;DCB Iterations +!HISTORY_MSG_115;False Color Suppression +!HISTORY_MSG_116;DCB Enhancement +!HISTORY_MSG_117;Raw Red CA Correction +!HISTORY_MSG_118;Raw Blue CA Correction +!HISTORY_MSG_119;Line Noise Filter +!HISTORY_MSG_120;Green Equilibration +!HISTORY_MSG_121;Raw Auto CA +!HISTORY_MSG_122;Dark Frame Auto Select +!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 Select +!HISTORY_MSG_128;Flat Field Blur Radius +!HISTORY_MSG_129;Flat Field Blur Type +!HISTORY_MSG_130;Auto Distorion +!HISTORY_MSG_131;Noise Reduction Luma +!HISTORY_MSG_132;Noise Reduction 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;Edges Sharpening +!HISTORY_MSG_147;ES - Luminance Only +!HISTORY_MSG_148;Microcontrast +!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_150;Post Demosaic Artifact/Noise Reduction +!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;'CC' curve +!HISTORY_MSG_169;'CH' curve +!HISTORY_MSG_170;Vib - Curve +!HISTORY_MSG_171;'LC' curve +!HISTORY_MSG_172;Lab - 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 tones protection +!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 pixels +!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;'CL' curve +!HISTORY_MSG_247;'LH' curve +!HISTORY_MSG_248;'HH' curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +!MAIN_BUTTON_FULLSCREEN;Fullscreen +!MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the Next image relative to image open in Editor\nShortcut: Shift-F4\n\nTo navigate to the Next image relative to thumbnail selected in File Browser\nShortcut: F4 +!MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the Previous image relative to image open in Editor\nShortcut: Shift-F3 \n\nTo navigate to the Previous image relative to thumbnail selected in File Browser\nShortcut: F3 +!MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronize the File Browser with the Editor to reveal the thumbnail of the currently open image, and clear filters in File Browser \nShortcut: x\n\nAs above, but without clearing filters in File Browser\nShortcut: y\n(Note that thumbnail of the open file 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\ndoesn't exist. Please set a correct path in the Preference window. +!MAIN_MSG_SETPATHFIRST;You have to set a target path first in Preferences\nin order to use this function! +!MAIN_MSG_WRITEFAILED;Failed to write\n\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_METADATA_TOOLTIP;Shortcut: Alt-m +!MAIN_TAB_RAW;Raw +!MAIN_TAB_RAW_TOOLTIP;Shortcut: Alt-r +!MAIN_TAB_TRANSFORM_TOOLTIP;Shortcut: Alt-t +!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 10-30%\n\nPreview is rendered slower with Focus Mask turned on. +!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_NA;B = n/a +!NAVIGATOR_B_VALUE;B = %1 +!NAVIGATOR_G_NA;G = n/a +!NAVIGATOR_G_VALUE;G = %1 +!NAVIGATOR_H_NA;H = n/a +!NAVIGATOR_H_VALUE;H = %1 +!NAVIGATOR_LAB_A_NA;a = n/a +!NAVIGATOR_LAB_A_VALUE;a = %1 +!NAVIGATOR_LAB_B_NA;b = n/a +!NAVIGATOR_LAB_B_VALUE;b = %1 +!NAVIGATOR_LAB_L_NA;L = n/a +!NAVIGATOR_LAB_L_VALUE;L = %1 +!NAVIGATOR_R_NA;R = n/a +!NAVIGATOR_R_VALUE;R = %1 +!NAVIGATOR_S_NA;S = n/a +!NAVIGATOR_S_VALUE;S = %1 +!NAVIGATOR_V_NA;V = n/a +!NAVIGATOR_V_VALUE;V = %1 +!NAVIGATOR_XY_FULL;Width = %1, Height = %2 +!NAVIGATOR_XY_NA;x = n/a, y = n/a +!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;CIE Color Appearance Model 2002 +!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_EVERYTHING;Everything +!PARTIALPASTE_FLATFIELDAUTOSELECT;Flat field auto selection +!PARTIALPASTE_FLATFIELDBLURRADIUS;Flat field blur radius +!PARTIALPASTE_FLATFIELDBLURTYPE;Flat field blur type +!PARTIALPASTE_FLATFIELDFILE;Flat field file +!PARTIALPASTE_GRADIENT;Graduated filter +!PARTIALPASTE_HSVEQUALIZER;HSV equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!PARTIALPASTE_LABCURVE;Lab adjustments +!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_PERSPECTIVE;Perspective +!PARTIALPASTE_PREPROCESS_GREENEQUIL;Green equilibration +!PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Apply hot/dead 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_ALLENHANCE;Post-demosaic artifact/noise reduction +!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 +!PREFERENCES_ADD;Add +!PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!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_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_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 scipts 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_DATEFORMATFRAME;Date Format +!PREFERENCES_DIRDARKFRAMES;Dark frames directory +!PREFERENCES_EDITORLAYOUT;Editor Layout +!PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar (de-select for low resolution display) +!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_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;Output device's Yb luminance (%) +!PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogram in left panel +!PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Show embedded JPEG thumbnail if raw is unedited +!PREFERENCES_LANGAUTODETECT;Use OS language setting +!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_MULTITABDUALMON;Multiple Editor Tabs Mode (if available on second monitor) +!PREFERENCES_MULTITAB;Multiple Editor Tabs Mode +!PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails +!PREFERENCES_OVERWRITEOUTPUTFILE;Overwrite existing output files +!PREFERENCES_PANFACTORFRAME;Pan Rate Amplification +!PREFERENCES_PANFACTORLABEL;Factor +!PREFERENCES_PROPERTY;Property +!PREFERENCES_RGBDTL_LABEL;Max number of threads for Noise Reduction +!PREFERENCES_RGBDTL_TOOLTIP;Noise Reduction requires a baseline of about 128MB RAM for a 10MPix image or 512MB for a 40MPix image, and additionally 128MB RAM per thread. The more threads run in parallel, the faster the computation. Leave the setting at "0" to automatically use as many threads as possible. +!PREFERENCES_SELECTFONT;Select font +!PREFERENCES_SET;Set +!PREFERENCES_SHOWEXPOSURECOMPENSATION;Append exposure compensation +!PREFERENCES_SHOWPROFILESELECTOR;Show processing profile selector +!PREFERENCES_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs +!PREFERENCES_SINGLETAB;Single Editor Tab Mode +!PREFERENCES_SLIMUI;Slim interface +!PREFERENCES_SND_BATCHQUEUEDONE;Queue processing done +!PREFERENCES_SND_HELP;Either enter filepath or nothing (for no sound).\nOn Windows use "SystemDefault", "SystemAsterisk" etc. for system sounds.\nOn Linux use "complete", "window-attention" etc. for system sounds. +!PREFERENCES_SND_LNGEDITPROCDONE;Editor processing done +!PREFERENCES_SND_TRESHOLDSECS;after secs +!PREFERENCES_SQUAREDETAILWINDOW;Square detail window (faster) +!PREFERENCES_TAB_PERFORMANCE;Performance +!PREFERENCES_TAB_SOUND;Sounds +!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_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_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing channel-mixer +!TP_BWMIX_BLUE;Blue +!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;Modify luminance in function of hue\nPay attention to extreme values that may cause artifacts +!TP_BWMIX_CYAN;Cyan +!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 simulate shots taken with a colored filter placed in front of the lens. Colored filters reduce transmission of specific range of colors and correspondingly affect their lightness. E.g. a Red filter darkens Blue skies. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_BLUE;Blue Channel +!TP_BWMIX_GAM_GREEN;Green Channel +!TP_BWMIX_GAM_RED;Red Channel +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each channel RGB +!TP_BWMIX_GREEN;Green +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MAGENTA;Magenta +!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 (filter, channel-mixer) to default +!TP_BWMIX_ORANGE;Orange +!TP_BWMIX_PURPLE;Purple +!TP_BWMIX_RED;Red +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all of the mixer options\nTotal displays the sum of RGB values actually applied:\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 (films, landscape, ...) or manual settings of channel-mixer +!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;Channel-Mixer absolute RGB +!TP_BWMIX_SET_RGBREL;Channel-Mixer relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Channel-Mixer absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Channel-Mixer 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_BWMIX_YELLOW;Yellow +!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) RT 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.\n 0=no effect 1=median 2=gaussian.\n\nThese artifacts are due to limitations of CIECAM02. Alternatively, adjust the image to avoid very dark shadows. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from Lab and RGB brightness +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from Lab and RGB colorfulness +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from Lab and RGB saturation +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from Lab 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 Lab and RGB contrast +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from Lab and RGB contrast +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L (Lab) 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 (Lab) 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 Lab values before CIECAM02 adjustments +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RT 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 (Lab) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in Lab 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 Lab and RGB lightness +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model\n\nWB [RT] + [output]:\nRT's white balance is used for the scene, CIECAM02 is set to D50, the output device's white balance is set in Preferences > Color Management\n\nWB [RT+CAT02] + [output]:\nRT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences +!TP_COLORAPP_RSTPRO;Red & skin tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin tones protection (sliders and curves) +!TP_COLORAPP_SHARPCIE;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe with Q/C +!TP_COLORAPP_SHARPCIE_TOOLTIP;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe will use CIECAM02 if enabled. +!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;Change tones and colors to take into account the viewing conditions of the output device\n\nAverage:\nAverage light environment (standard)\nThe image will not change\n\nDim:\nDim environment (TV)\nThe image will become slighty dark\n\nDark:\nDark environment (projector)\nThe image will become more dark\n\nExtremly Dark:\nExtremly dark environment (cutsheet)\nThe image will become very dark +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if source 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 Lab 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_CROP_GTEPASSPORT;Biometric Passport +!TP_CROP_GTFRAME;Frame +!TP_CROP_GTGRID;Grid +!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_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_CHROMA;Chrominance - Master +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on gamma of the input color profile. Gamma of sRGB is assumed, thus if input image is in color profile of a different gamma, luminance noise reduction will vary. +!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_LAB;Lab +!TP_DIRPYRDENOISE_LDETAIL;Luminance Detail +!TP_DIRPYRDENOISE_LUMA;Luminance +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or Lab methods can be used.\n\nFor non-raw images Lab method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_PERF;RGB mode (raw images) +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGB;RGB +!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_THRESHOLD;Threshold +!TP_DISTORTION_AUTO;Auto Distortion Correction +!TP_DISTORTION_AUTO_TIP;(Exprimental) Correct lens distortion automatically for some cameras (Micro 4/3, some compact digital cameras, etc.) +!TP_EPD_EDGESTOPPING;Edge Stopping +!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 via Lab mode (standard) and CIECAM02 mode.\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_EXPOSCORR_LABEL;Raw White & Black Points +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggle execution of auto levels to automatically set parameter values based on image analysis\nEnable Highlight Reconstruction if necessary +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in auto level's 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 following section of the manual to learn how to achieve the best results with double curves:\nThe Toolbox > Exposure Tab > Exposure Panel > Tone Curve +!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_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!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_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 effect of this tool or some of its sub-component is only visible at 1:1 preview scale. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Rotation anchor point X: -100=left edge, 0=center, +100=right edge +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Rotation anchor point Y: -100=top edge, 0=center, +100=bottom edge +!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 automatic exposure +!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 blown 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 simple color matrix by dcraw, enhanced RawTherapee version (whichever is available based on camera model) or embedded in 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. Use only in special cases. +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. Result can be used for calibration purposes, 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;Lab 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;Can be used with the Chromaticity slider and the CC curve. +!TP_LENSGEOM_AUTOCROP;Auto Crop +!TP_LENSGEOM_FILL;Auto fill +!TP_LENSGEOM_LABEL;Lens / Geometry +!TP_LENSPROFILE_FILEDLGFILTERLCP;Lens correction files +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;CA Correction +!TP_LENSPROFILE_USEDIST;Distortion correction +!TP_LENSPROFILE_USEVIGN;Vignetting correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset 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: 0=corners only, 50=halfway to center, 100=to center +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness: 0=rectangle, 50=fitted ellipse, 100=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. Higher = more, lower = less. +!TP_PREPROCESS_GREENEQUIL;Green Equilibration +!TP_PREPROCESS_HOTDEADPIXFILT;Hot/Dead pixel filter +!TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Try to suppress hot and dead 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_BLACKONE;Black Level: Red +!TP_RAWEXPOS_BLACKS;Black Levels +!TP_RAWEXPOS_BLACKTHREE;Black Level: Green 2 +!TP_RAWEXPOS_BLACKTWO;Black Level: Blue +!TP_RAWEXPOS_BLACKZERO;Black Level: Green 1 (lead) +!TP_RAWEXPOS_LINEAR;White Point Correction +!TP_RAWEXPOS_PRESER;Highlight Preservation +!TP_RAWEXPOS_TWOGREEN;Link greens +!TP_RAW_ALLENHANCE;Post-Demosaic Artifact/Noise Reduction +!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 +!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_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 used 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_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_ZOOMFITSCREEN;Fit 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..cbc723aaa --- /dev/null +++ b/rtdata/languages/Deutsch @@ -0,0 +1,1457 @@ +#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_FILEDLGFILTERANY;Alle Dateien +CURVEEDITOR_FILEDLGFILTERCURVE;Kurvendateien +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 +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_COLORDENOISE;Farb-Rauschfilter umgehen +EXPORT_BYPASS_DEFRINGE;Defringe umgehen +EXPORT_BYPASS_DIRPYRDENOISE;Rauschminderung umgehen +EXPORT_BYPASS_DIRPYREQUALIZER;Kontrast nach Detailstufen umgehen +EXPORT_BYPASS_LUMADENOISE;Luminanz-Rauschfilter umgehen +EXPORT_BYPASS_RAW_ALL_ENHANCE;Artifakt-/Rauschminderung nach\nFarbinterpolation umgehen [RAW] +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 +EXPORT_RESIZEMETHOD;Größe ändern\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_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 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_USETEMPLATE;Vorlage verwenden: +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_TAGGING;Tagging +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_B_NA;B = k.a. +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_G_NA;G = k.a. +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_H_NA;H = k.a. +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_LAB_A_NA;a = k.a. +NAVIGATOR_LAB_A_VALUE;a = %1 +NAVIGATOR_LAB_B_NA;b = k.a. +NAVIGATOR_LAB_B_VALUE;b = %1 +NAVIGATOR_LAB_L_NA;L = k.a. +NAVIGATOR_LAB_L_VALUE;L = %1 +NAVIGATOR_R_NA;R = k.a. +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_S_NA;S = k.a. +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_NA;V = k.a. +NAVIGATOR_V_VALUE;V = %1 +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_METAICMGROUP;Gruppe Metadaten / ICM +PARTIALPASTE_PCVIGNETTE;Vignettierungsfilter +PARTIALPASTE_PERSPECTIVE;Perspektive +PARTIALPASTE_PREPROCESS_GREENEQUIL;Vorverarbeitung: Grün-Ausgleich +PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Vorverarbeitung: Hot/Dead-Pixel-Filter anwenden +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_ALLENHANCE;Farbinterpolation: Artifakt-/Rauschminderung +PARTIALPASTE_RAW_DCBENHANCE;Farbinterpolation: DCB-Verfeinerungsschritt durchführen +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_BLINKCLIPPED;Zu helle/dunkle Bereiche anzeigen +PREFERENCES_CACHECLEARALL;Alles löschen +PREFERENCES_CACHECLEARPROFILES;Profile löschen +PREFERENCES_CACHECLEARTHUMBS;Voransichten löschen +PREFERENCES_CACHEFORMAT1;Proprietär (schneller und höhere Qualität) +PREFERENCES_CACHEFORMAT2;JPEG (geringerer Speicherplatzbedarf) +PREFERENCES_CACHEMAXENTRIES;Höchstzahl der Einträge im Zwischenspeicher +PREFERENCES_CACHEOPTS;Einstellungen des Zwischenspeichers für Voransichten (Cache) +PREFERENCES_CACHETHUMBFORM;Format der Voransichten +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_DATEFORMATFRAME;Datumsformat +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_GTKTHEME;Standard GTK +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_PANFACTORFRAME;Hand-Werkzeug +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_SHOWPROFILESELECTOR;Profilauswahl anzeigen +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_SQUAREDETAILWINDOW;Quadratisches Detailfenster (schneller) +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_FILEDLGFILTERANY;Alle Dateien +PROFILEPANEL_FILEDLGFILTERPP;Bearbeitungsprofile +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_JPGFILTER;JPEG-Datei +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_TIFFFILTER;TIFF-Datei +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_BLUE;Blau +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_BLUE;Blauer Kanal +TP_BWMIX_GAM_GREEN;Grüner Kanal +TP_BWMIX_GAM_RED;Roter Kanal +TP_BWMIX_GAM_TOOLTIP;Korrigiere Gamma für einzelne RGB-Kanäle +TP_BWMIX_GREEN;Grün +TP_BWMIX_LABEL;Schwarzweiß +TP_BWMIX_MAGENTA;Magenta +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_SET_RGBABS;Kanal-Mixer abs. RGB +TP_BWMIX_SET_RGBREL;Kanal-Mixer rel. RGB +TP_BWMIX_SET_ROYGCBPMABS;Kanal-Mixer abs. ROYGCBPM +TP_BWMIX_SET_ROYGCBPMREL;Kanal-Mixer rel. ROYGCBPM +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_DEGREE;Grad: +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_COLORBOOST_ACHANNEL;Kanal "a" +TP_COLORBOOST_AMOUNT;Stärke +TP_COLORBOOST_AVOIDCOLORCLIP;Übersättigung verhindern +TP_COLORBOOST_BCHANNEL;Kanal "b" +TP_COLORBOOST_CHANNEL;Kanal +TP_COLORBOOST_CHSEPARATE;separat +TP_COLORBOOST_ENABLESATLIMITER;Sättigungsbegrenzung aktivieren +TP_COLORBOOST_LABEL;Farbverstärkung +TP_COLORBOOST_SATLIMIT;Sättigungsgrenze +TP_COLORDENOISE_EDGESENSITIVE;Kantenempfindlichkeit +TP_COLORDENOISE_EDGETOLERANCE;Kantentoleranz +TP_COLORDENOISE_LABEL;Farb-Rauschfilter +TP_COLORDENOISE_RADIUS;Radius +TP_COLORSHIFT_BLUEYELLOW;Blau-Gelb +TP_COLORSHIFT_GREENMAGENTA;Grün-Magenta +TP_COLORSHIFT_LABEL;Farbverschiebung +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_GTHARMMEANS1;Harmonischer Schnitt 1 +TP_CROP_GTHARMMEANS2;Harmonischer Schnitt 2 +TP_CROP_GTHARMMEANS3;Harmonischer Schnitt 3 +TP_CROP_GTHARMMEANS4;Harmonischer Schnitt 4 +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_DETAIL_AMOUNT;Stärke +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_PERF;RGB Modus (Raw-Bilder) +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_EQUALIZER_CONTRAST_MINUS;Kontrast- +TP_EQUALIZER_CONTRAST_PLUS;Kontrast+ +TP_EQUALIZER_FINEST;Feinstes +TP_EQUALIZER_LABEL;Wavelet-Mixer +TP_EQUALIZER_LARGEST;Gröbstes +TP_EQUALIZER_NEUTRAL;Neutral +TP_EXPOSCORR_LABEL;RAW-Weiß/Schwarz-Punkt +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_EXPO_AFTER;Nach Interpolation (vor RGB-Konvertierung) +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_FILEDLGFILTERANY;Alle Dateien +TP_ICM_FILEDLGFILTERICM;Profildateien +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_PREFERREDPROFILE;Bevorzugtes DCP-Profil +TP_ICM_PREFERREDPROFILE_1;Tageslicht +TP_ICM_PREFERREDPROFILE_2;Glühlampe +TP_ICM_PREFERREDPROFILE_3;Leuchtstofflampe +TP_ICM_PREFERREDPROFILE_4;Blitz +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_AVOIDCOLORCLIP;Farbbeschneidungen verhindern +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_BWTONING;S&W Tonung +TP_LABCURVE_BWTONING_TIP;Wenn die Option S&W Tonung aktiviert ist, haben die Lab Chromatizität, CC, CH und LC Kurven keine Auswirkung.\nTonung kann mithilfe der a und b Kurven erzielt werden. +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_ENABLESATLIMITER;Sättigungsbegrenzung aktivieren +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_LABCURVE_SATLIMIT;Sättigungsgrenze +TP_LABCURVE_SATURATION;Sättigung +TP_LENSGEOM_AUTOCROP;Auto-Schneiden +TP_LENSGEOM_FILL;Auto-Füllen +TP_LENSGEOM_LABEL;Objektivkorrekturen +TP_LENSPROFILE_FILEDLGFILTERLCP;Linsen-Korrekturdateien +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_GREENEQUIL;Grün-Ausgleich +TP_PREPROCESS_HOTDEADPIXFILT;Hot/Dead-Pixel-Filter anwenden +TP_PREPROCESS_HOTDEADPIXTHRESH;Hot/Dead-Pixel-Erkennung\nSchwellenwert +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_BLACKONE;Schwarzpegel: Rot +TP_RAWEXPOS_BLACKS;Schwarzpegel +TP_RAWEXPOS_BLACKTHREE;Schwarzpegel: Grün 2 +TP_RAWEXPOS_BLACKTWO;Schwarzpegel: Blau +TP_RAWEXPOS_BLACKZERO;Schwarzpegel: Grün 1\n(führend) +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_ALLENHANCE;Artifakt-/Rauschminderung nach\nFarbinterpolation durchführen +TP_RAW_DCBENHANCE;DCB-Verfeinerungsschritt durchführen +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_BICUBICSF;Bikubisch (weicher) +TP_RESIZE_BICUBICSH;Bikubisch (schärfer) +TP_RESIZE_BICUBIC;Bikubisch +TP_RESIZE_BILINEAR;Bilinear +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 +!EXPORT_BYPASS_RAW_LMMSE_ITERATIONS;Bypass [raw] LMMSE Enhancement Steps +!HISTORY_MSG_204;LMMSE Enhancement Steps +!HISTORY_MSG_205;CAM02 - Hot/bad pixels +!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 +!MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the Next image relative to image open in Editor\nShortcut: Shift-F4\n\nTo navigate to the Next image relative to thumbnail selected in File Browser\nShortcut: F4 +!MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the Previous image relative to image open in Editor\nShortcut: Shift-F3 \n\nTo navigate to the Previous image relative to thumbnail selected in File Browser\nShortcut: F3 +!MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronize the File Browser with the Editor to reveal the thumbnail of the currently open image, and clear filters in File Browser \nShortcut: x\n\nAs above, but without clearing filters in File Browser\nShortcut: y\n(Note that thumbnail of the open file will not be shown if filtered out). +!MAIN_MSG_OPERATIONCANCELLED;Operation cancelled +!MAIN_MSG_PATHDOESNTEXIST;The path\n\n%1\n\ndoesn't exist. Please set a correct path in the Preference window. +!MAIN_MSG_SETPATHFIRST;You have to set a target path first in Preferences\nin order to use this function! +!PARTIALPASTE_CHANNELMIXERBW;Black-and-White +!PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!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_CUSTPROFBUILDKEYFORMAT;Keys format +!PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Name +!PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID +!PREFERENCES_USEBUNDLEDPROFILES;Use bundled profiles +!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_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;Modify luminance in function of hue\nPay attention to extreme values that may cause artifacts +!TP_BWMIX_CYAN;Cyan +!TP_BWMIX_NEUTRAL_TIP;Reset all values (filter, channel-mixer) to default +!TP_BWMIX_ORANGE;Orange +!TP_BWMIX_PURPLE;Purple +!TP_BWMIX_RED;Red +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all of the mixer options\nTotal displays the sum of RGB values actually applied:\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_TCMODE_SATANDVALBLENDING;B&W Saturation and Value Blending +!TP_BWMIX_VAL;L +!TP_BWMIX_YELLOW;Yellow +!TP_COLORAPP_ADAP_AUTO_TOOLTIP;If the checkbox is checked (recommended) RT 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.\n 0=no effect 1=median 2=gaussian.\n\nThese artifacts are due to limitations of CIECAM02. Alternatively, adjust the image to avoid very dark shadows. +!TP_DIRPYRDENOISE_ENH;Enhanced mode +!TP_DIRPYRDENOISE_ENH_TOOLTIP;Increases noise reduction quality at the expense of a 20% processing time increase +!TP_GENERAL_11SCALE_TOOLTIP;The effect of this tool or some of its sub-component is only visible at 1:1 preview scale. +!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_TOOLTIP;Save the linear TIFF image before the input profile is applied. Result can be used for calibration purposes, 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. Higher = more, lower = less. +!TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Try to suppress hot and dead pixels +!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 +!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_SAVEDIALOG_OK_TIP;Shortcut Ctrl-Enter +!TP_SHADOWSHLIGHTS_SHARPMASK;Sharp mask +!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 diff --git a/rtdata/languages/English (UK) b/rtdata/languages/English (UK) new file mode 100644 index 000000000..54d8408d1 --- /dev/null +++ b/rtdata/languages/English (UK) @@ -0,0 +1,1395 @@ +EXPORT_BYPASS_COLORDENOISE;Bypass Colour denoise +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 Colour label.\nShortcut: Alt-0 +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;Lab - 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 +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_COLORAPP;CIE Colour Appearance Model 2002 +PARTIALPASTE_COLORGROUP;Colour Related Settings +PARTIALPASTE_ICMSETTINGS;Colour management settings +PARTIALPASTE_METAICMGROUP;Metadata/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_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 simulate shots taken with a coloured filter placed in front of the lens. Coloured filters reduce transmission of specific range of colours and correspondingly affect their lightness. E.g. a Red filter darkens Blue skies. +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.\n 0=no effect 1=median 2=gaussian.\n\nThese artifacts are due to limitations of CIECAM02. Alternatively, adjust the image to avoid very dark shadows. +TP_COLORAPP_CHROMA_M;Colourfulnes (M) +TP_COLORAPP_CHROMA_M_TOOLTIP;Colourfulness in CIECAM02 differs from Lab and RGB colourfulness +TP_COLORAPP_CURVEEDITOR3;Colour curve +TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Adjust either chroma, saturation or colourfulness.\n\nShows the histogram of chromaticity (Lab) 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]:\nRT's white balance is used for the scene, CIECAM02 is set to D50, the output device's white balance is set in Preferences > Colour Management\n\nWB [RT+CAT02] + [output]:\nRT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences +TP_COLORAPP_SURROUND_TOOLTIP;Change tones and colours to take into account the viewing conditions of the output device\n\nAverage:\nAverage light environment (standard)\nThe image will not change\n\nDim:\nDim environment (TV)\nThe image will become slighty dark\n\nDark:\nDark environment (projector)\nThe image will become more dark\n\nExtremly Dark:\nExtremly dark environment (cutsheet)\nThe image will become very dark +TP_COLORAPP_TCMODE_COLORF;Colourfulness +TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on gamma of the input colour profile. Gamma of sRGB is assumed, thus if input image is in colour profile of a different gamma, luminance noise reduction will vary. +TP_EPD_TOOLTIP;Tone mapping is possible via Lab mode (standard) and CIECAM02 mode.\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_GRADIENT_CENTER;Centre +TP_GRADIENT_CENTER_X;Centre X +TP_GRADIENT_CENTER_X_TOOLTIP;Rotation anchor point X: -100=left edge, 0=centre, +100=right edge +TP_GRADIENT_CENTER_Y;Centre Y +TP_GRADIENT_CENTER_Y_TOOLTIP;Rotation anchor point Y: -100=top edge, 0=centre, +100=bottom edge +TP_HLREC_COLOR;Colour Propagation +TP_ICM_FILEDLGFILTERICM;Colour profiles +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 simple colour matrix by dcraw, enhanced RawTherapee version (whichever is available based on camera model) or embedded in 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. Use 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: 0=corners only, 50=halfway to centre, 100=to centre +TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controls defringe strength by colour. Higher = more, lower = 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_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_CURVES;Curves +!CURVEEDITOR_CURVE;Curve +!CURVEEDITOR_CUSTOM;Custom +!CURVEEDITOR_DARKS;Darks +!CURVEEDITOR_FILEDLGFILTERANY;Any files +!CURVEEDITOR_FILEDLGFILTERCURVE;Curve files +!CURVEEDITOR_HIGHLIGHTS;Highlights +!CURVEEDITOR_LIGHTS;Lights +!CURVEEDITOR_LINEAR;Linear +!CURVEEDITOR_LOADDLGLABEL;Load Curve... +!CURVEEDITOR_MINMAXCPOINTS;Minima/Maxima control points +!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: +!EDITWINDOW_TITLE;Image Edit +!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_LUMADENOISE;Bypass Luma denoise +!EXPORT_BYPASS_RAW_ALL_ENHANCE;Bypass Post Demosaic Artifact/Noise Reduction +!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 +!EXPORT_RESIZEMETHOD;Resize 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.\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\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_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_POPUPOPEN;Open +!FILEBROWSER_POPUPPROCESSFAST;Put to Queue (Fast export) +!FILEBROWSER_POPUPPROCESS;Put to Queue +!FILEBROWSER_POPUPPROFILEOPERATIONS;Processing Profile Operations +!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 a partial filename to search for or a comma-separated list.\nE.g. 1001,1004,1199 \n\nCtrl-F to focus to the Find text box.\nEnter to commence search.\nEsc to clear.\nShift-Esc to remove focus. +!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.\nShortcut: i\n\nShortcut in Single Editor Tab Mode: Alt-i +!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 images recently saved.\nShortcut: Alt-7 +!FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show images not recently saved.\nShortcut: Alt-6 +!FILEBROWSER_SHOWTRASHHINT;Show content of the trash.\nShortcut: 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_USETEMPLATE;Use template: +!FILEBROWSER_ZOOMINHINT;Increase thumbnail size.\nShortcut: +\n\nShortcut in Single Editor Tab Mode: Alt-+ +!FILEBROWSER_ZOOMOUTHINT;Decrease thumbnail size.\nShortcut: -\n\nShortcut in Single Editor Tab Mode: Alt-- +!GENERAL_ABOUT;About +!GENERAL_AFTER;After +!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\nClick right mouse button 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 (on) or scaled (off) 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;Lab - Lightness +!HISTORY_MSG_15;Lab - Contrast +!HISTORY_MSG_16;Luminance Black +!HISTORY_MSG_17;Luminance Highlight Compr. +!HISTORY_MSG_18;Luminance Shadow Compr. +!HISTORY_MSG_19;'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 Mode 1 +!HISTORY_MSG_42;Tone Curve 2 +!HISTORY_MSG_43;Tone Curve Mode 2 +!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;HL 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;Data specified for resize +!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;Lab - Chromaticity +!HISTORY_MSG_96;'a' Curve +!HISTORY_MSG_97;'b' Curve +!HISTORY_MSG_98;Demosaicing Method +!HISTORY_MSG_99;Hot/Dead pixel filter +!HISTORY_MSG_100;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;Resizing applies to +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;Lab - Protection +!HISTORY_MSG_114;DCB Iterations +!HISTORY_MSG_116;DCB Enhancement +!HISTORY_MSG_117;Raw Red CA Correction +!HISTORY_MSG_118;Raw Blue CA Correction +!HISTORY_MSG_119;Line Noise Filter +!HISTORY_MSG_120;Green Equilibration +!HISTORY_MSG_121;Raw Auto CA +!HISTORY_MSG_122;Dark Frame Auto Select +!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 Select +!HISTORY_MSG_128;Flat Field Blur Radius +!HISTORY_MSG_129;Flat Field Blur Type +!HISTORY_MSG_130;Auto Distorion +!HISTORY_MSG_131;Noise Reduction Luma +!HISTORY_MSG_132;Noise Reduction 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;Edges Sharpening +!HISTORY_MSG_147;ES - Luminance Only +!HISTORY_MSG_148;Microcontrast +!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_150;Post Demosaic Artifact/Noise Reduction +!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;'CC' curve +!HISTORY_MSG_169;'CH' curve +!HISTORY_MSG_170;Vib - Curve +!HISTORY_MSG_171;'LC' curve +!HISTORY_MSG_172;Lab - 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 tones protection +!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 pixels +!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;'CL' curve +!HISTORY_MSG_247;'LH' curve +!HISTORY_MSG_248;'HH' curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!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 open in Editor\nShortcut: Shift-F4\n\nTo navigate to the Next image relative to thumbnail selected in File Browser\nShortcut: F4 +!MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the Previous image relative to image open in Editor\nShortcut: Shift-F3 \n\nTo navigate to the Previous image relative to thumbnail selected in File Browser\nShortcut: F3 +!MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronize the File Browser with the Editor to reveal the thumbnail of the currently open image, and clear filters in File Browser \nShortcut: x\n\nAs above, but without clearing filters in File Browser\nShortcut: y\n(Note that thumbnail of the open file 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 the "Preferences" dialog. +!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\ndoesn't exist. Please set a correct path in the Preference window. +!MAIN_MSG_QOVERWRITE;Do you want to overwrite it? +!MAIN_MSG_SETPATHFIRST;You have to set a target path first in Preferences\nin order to use this function! +!MAIN_MSG_WRITEFAILED;Failed to write\n\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_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_TAGGING;Tagging +!MAIN_TAB_TRANSFORM;Transform +!MAIN_TAB_TRANSFORM_TOOLTIP;Shortcut: Alt-t +!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 10-30%\n\nPreview is rendered slower with Focus Mask turned on. +!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_NA;B = n/a +!NAVIGATOR_B_VALUE;B = %1 +!NAVIGATOR_G_NA;G = n/a +!NAVIGATOR_G_VALUE;G = %1 +!NAVIGATOR_H_NA;H = n/a +!NAVIGATOR_H_VALUE;H = %1 +!NAVIGATOR_LAB_A_NA;a = n/a +!NAVIGATOR_LAB_A_VALUE;a = %1 +!NAVIGATOR_LAB_B_NA;b = n/a +!NAVIGATOR_LAB_B_VALUE;b = %1 +!NAVIGATOR_LAB_L_NA;L = n/a +!NAVIGATOR_LAB_L_VALUE;L = %1 +!NAVIGATOR_R_NA;R = n/a +!NAVIGATOR_R_VALUE;R = %1 +!NAVIGATOR_S_NA;S = n/a +!NAVIGATOR_S_VALUE;S = %1 +!NAVIGATOR_V_NA;V = n/a +!NAVIGATOR_V_VALUE;V = %1 +!NAVIGATOR_XY_FULL;Width = %1, Height = %2 +!NAVIGATOR_XY_NA;x = n/a, y = n/a +!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;90° rotation / flipping +!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_EVERYTHING;Everything +!PARTIALPASTE_EXIFCHANGES;Changes to Exif data +!PARTIALPASTE_EXPOSURE;Exposure +!PARTIALPASTE_FLATFIELDAUTOSELECT;Flat field auto selection +!PARTIALPASTE_FLATFIELDBLURRADIUS;Flat field blur radius +!PARTIALPASTE_FLATFIELDBLURTYPE;Flat field blur type +!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 info +!PARTIALPASTE_LABCURVE;Lab adjustments +!PARTIALPASTE_LENSGROUP;Lens Related Settings +!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_PERSPECTIVE;Perspective +!PARTIALPASTE_PREPROCESS_GREENEQUIL;Green equilibration +!PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Apply hot/dead 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_ALLENHANCE;Post-demosaic artifact/noise reduction +!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_WHITEBALANCE;White balance +!PREFERENCES_ADD;Add +!PREFERENCES_APPLNEXTSTARTUP;restart required +!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_BLINKCLIPPED;Blink clipped areas +!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_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_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 scipts 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_DATEFORMATFRAME;Date Format +!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;Date format +!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_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_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_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_GREY;Output device's Yb luminance (%) +!PREFERENCES_GTKTHEME;GTK default +!PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogram in left panel +!PREFERENCES_HLTHRESHOLD;Threshold for clipped highlights +!PREFERENCES_IMPROCPARAMS;Default Image Processing Parameters +!PREFERENCES_INTENT_PERCEPTUAL;Perceptual +!PREFERENCES_INTENT_SATURATION;Saturation +!PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Show embedded JPEG thumbnail if raw is unedited +!PREFERENCES_LANGAUTODETECT;Use OS language setting +!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_MULTITABDUALMON;Multiple Editor Tabs Mode (if available on second monitor) +!PREFERENCES_MULTITAB;Multiple Editor Tabs Mode +!PREFERENCES_OUTDIRFOLDERHINT;Put the saved 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 +!PREFERENCES_OVERWRITEOUTPUTFILE;Overwrite existing output files +!PREFERENCES_PANFACTORFRAME;Pan Rate Amplification +!PREFERENCES_PANFACTORLABEL;Factor +!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;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_RGBDTL_LABEL;Max number of threads for Noise Reduction +!PREFERENCES_RGBDTL_TOOLTIP;Noise Reduction requires a baseline of about 128MB RAM for a 10MPix image or 512MB for a 40MPix image, and additionally 128MB RAM per thread. The more threads run in parallel, the faster the computation. Leave the setting at "0" to automatically use as many threads as possible. +!PREFERENCES_SELECTFONT;Select font +!PREFERENCES_SELECTLANG;Select language +!PREFERENCES_SELECTTHEME;Select theme +!PREFERENCES_SET;Set +!PREFERENCES_SHOWBASICEXIF;Show basic Exif info +!PREFERENCES_SHOWDATETIME;Show date and time +!PREFERENCES_SHOWEXPOSURECOMPENSATION;Append exposure compensation +!PREFERENCES_SHOWPROFILESELECTOR;Show processing profile selector +!PREFERENCES_SHTHRESHOLD;Threshold for clipped shadows +!PREFERENCES_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs +!PREFERENCES_SINGLETAB;Single Editor Tab Mode +!PREFERENCES_SLIMUI;Slim interface +!PREFERENCES_SND_BATCHQUEUEDONE;Queue processing done +!PREFERENCES_SND_HELP;Either enter filepath or nothing (for no sound).\nOn Windows use "SystemDefault", "SystemAsterisk" etc. for system sounds.\nOn Linux use "complete", "window-attention" etc. for system sounds. +!PREFERENCES_SND_LNGEDITPROCDONE;Editor processing done +!PREFERENCES_SND_TRESHOLDSECS;after secs +!PREFERENCES_SQUAREDETAILWINDOW;Square detail window (faster) +!PREFERENCES_STARTUPIMDIR;Image Directory at Startup +!PREFERENCES_TAB_BROWSER;File Browser +!PREFERENCES_TAB_GENERAL;General +!PREFERENCES_TAB_IMPROC;Image Processing +!PREFERENCES_TAB_PERFORMANCE;Performance +!PREFERENCES_TAB_SOUND;Sounds +!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_WORKFLOW;Layout +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_FILEDLGFILTERANY;Any files +!PROFILEPANEL_FILEDLGFILTERPP;Processing profiles +!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_JPGFILTER;JPEG files +!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_TIFFFILTER;TIFF files +!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_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing channel-mixer +!TP_BWMIX_BLUE;Blue +!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;Modify luminance in function of hue\nPay attention to extreme values that may cause artifacts +!TP_BWMIX_CYAN;Cyan +!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_BLUE;Blue Channel +!TP_BWMIX_GAM_GREEN;Green Channel +!TP_BWMIX_GAM_RED;Red Channel +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each channel RGB +!TP_BWMIX_GREEN;Green +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MAGENTA;Magenta +!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 (filter, channel-mixer) to default +!TP_BWMIX_ORANGE;Orange +!TP_BWMIX_PURPLE;Purple +!TP_BWMIX_RED;Red +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all of the mixer options\nTotal displays the sum of RGB values actually applied:\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 (films, landscape, ...) or manual settings of channel-mixer +!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;Channel-Mixer absolute RGB +!TP_BWMIX_SET_RGBREL;Channel-Mixer relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Channel-Mixer absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Channel-Mixer 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_BWMIX_YELLOW;Yellow +!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.\nShortcut: [\n\nShortcut in Single Editor Tab: Alt-[ +!TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotate right.\nShortcut: ]\n\nShortcut in Single Editor Tab: Alt-] +!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) RT 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 Lab and RGB brightness +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from Lab and RGB saturation +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from Lab 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 Lab and RGB contrast +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from Lab and RGB contrast +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L (Lab) 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 Lab values before CIECAM02 adjustments +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RT 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 (Lab) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in Lab 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 Lab and RGB lightness +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_RSTPRO;Red & skin tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin tones protection (sliders and curves) +!TP_COLORAPP_SHARPCIE;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe with Q/C +!TP_COLORAPP_SHARPCIE_TOOLTIP;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe will use CIECAM02 if enabled. +!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 source 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 Lab 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_CROP_FIXRATIO;Fix ratio: +!TP_CROP_GTDIAGONALS;Rule of Diagonals +!TP_CROP_GTEPASSPORT;Biometric Passport +!TP_CROP_GTFRAME;Frame +!TP_CROP_GTGRID;Grid +!TP_CROP_GTHARMMEANS1;Harmonic Means 1 +!TP_CROP_GTHARMMEANS2;Harmonic Means 2 +!TP_CROP_GTHARMMEANS3;Harmonic Means 3 +!TP_CROP_GTHARMMEANS4;Harmonic Means 4 +!TP_CROP_GTNONE;None +!TP_CROP_GTRULETHIRDS;Rule of Thirds +!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_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_CHROMA;Chrominance - Master +!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_LAB;Lab +!TP_DIRPYRDENOISE_LDETAIL;Luminance Detail +!TP_DIRPYRDENOISE_LUMA;Luminance +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or Lab methods can be used.\n\nFor non-raw images Lab method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_PERF;RGB mode (raw images) +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGB;RGB +!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_THRESHOLD;Threshold +!TP_DISTORTION_AMOUNT;Amount +!TP_DISTORTION_AUTO;Auto Distortion Correction +!TP_DISTORTION_AUTO_TIP;(Exprimental) 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_LABEL;Tone Mapping +!TP_EPD_REWEIGHTINGITERATES;Reweighting Iterates +!TP_EPD_SCALE;Scale +!TP_EPD_STRENGTH;Strength +!TP_EXPOSCORR_LABEL;Raw White & Black Points +!TP_EXPOSURE_AUTOLEVELS;Auto Levels +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggle execution of auto levels to automatically set parameter values based on image analysis\nEnable 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 level's 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 following section of the manual to learn how to achieve the best results with double curves:\nThe Toolbox > Exposure Tab > Exposure Panel > Tone Curve +!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_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!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_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 effect of this tool or some of its sub-component is only visible at 1:1 preview scale. +!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 automatic exposure +!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 blown 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_FILEDLGFILTERANY;Any files +!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_TOOLTIP;Save the linear TIFF image before the input profile is applied. Result can be used for calibration purposes, 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;Lab 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;Can be used with the Chromaticity slider and the CC curve. +!TP_LENSGEOM_AUTOCROP;Auto Crop +!TP_LENSGEOM_FILL;Auto fill +!TP_LENSGEOM_LABEL;Lens / Geometry +!TP_LENSPROFILE_FILEDLGFILTERLCP;Lens correction files +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;CA Correction +!TP_LENSPROFILE_USEDIST;Distortion correction +!TP_LENSPROFILE_USEVIGN;Vignetting correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset 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: 0=rectangle, 50=fitted ellipse, 100=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_GREENEQUIL;Green Equilibration +!TP_PREPROCESS_HOTDEADPIXFILT;Hot/Dead pixel filter +!TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Try to suppress hot and dead 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_BLACKONE;Black Level: Red +!TP_RAWEXPOS_BLACKS;Black Levels +!TP_RAWEXPOS_BLACKTHREE;Black Level: Green 2 +!TP_RAWEXPOS_BLACKTWO;Black Level: Blue +!TP_RAWEXPOS_BLACKZERO;Black Level: Green 1 (lead) +!TP_RAWEXPOS_LINEAR;White Point Correction +!TP_RAWEXPOS_PRESER;Highlight Preservation +!TP_RAWEXPOS_TWOGREEN;Link greens +!TP_RAW_ALLENHANCE;Post-Demosaic Artifact/Noise Reduction +!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 +!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_RESIZE_APPLIESTO;Applies to: +!TP_RESIZE_BICUBICSF;Bicubic (Softer) +!TP_RESIZE_BICUBICSH;Bicubic (Sharper) +!TP_RESIZE_BICUBIC;Bicubic +!TP_RESIZE_BILINEAR;Bilinear +!TP_RESIZE_CROPPEDAREA;Cropped Area +!TP_RESIZE_FITBOX;Bounding Box +!TP_RESIZE_FULLIMAGE;Full Image +!TP_RESIZE_HEIGHT;Height +!TP_RESIZE_H;H: +!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;W: +!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;Tonal Width for Highlights +!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;Tonal Width for Shadows +!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 used 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_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_ZOOMFITSCREEN;Fit 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..b37750baf --- /dev/null +++ b/rtdata/languages/English (US) @@ -0,0 +1,1395 @@ +!!!!!!!!!!!!!!!!!!!!!!!!! +! 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_CURVES;Curves +!CURVEEDITOR_CURVE;Curve +!CURVEEDITOR_CUSTOM;Custom +!CURVEEDITOR_DARKS;Darks +!CURVEEDITOR_FILEDLGFILTERANY;Any files +!CURVEEDITOR_FILEDLGFILTERCURVE;Curve files +!CURVEEDITOR_HIGHLIGHTS;Highlights +!CURVEEDITOR_LIGHTS;Lights +!CURVEEDITOR_LINEAR;Linear +!CURVEEDITOR_LOADDLGLABEL;Load Curve... +!CURVEEDITOR_MINMAXCPOINTS;Minima/Maxima control points +!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: +!EDITWINDOW_TITLE;Image Edit +!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_COLORDENOISE;Bypass Color denoise +!EXPORT_BYPASS_DEFRINGE;Bypass Defringe +!EXPORT_BYPASS_DIRPYRDENOISE;Bypass Noise Reduction +!EXPORT_BYPASS_DIRPYREQUALIZER;Bypass Contrast by Detail Levels +!EXPORT_BYPASS_LUMADENOISE;Bypass Luma denoise +!EXPORT_BYPASS_RAW_ALL_ENHANCE;Bypass Post Demosaic Artifact/Noise Reduction +!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 +!EXPORT_RESIZEMETHOD;Resize 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.\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\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_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_POPUPOPEN;Open +!FILEBROWSER_POPUPPROCESSFAST;Put to Queue (Fast export) +!FILEBROWSER_POPUPPROCESS;Put to Queue +!FILEBROWSER_POPUPPROFILEOPERATIONS;Processing Profile Operations +!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 a partial filename to search for or a comma-separated list.\nE.g. 1001,1004,1199 \n\nCtrl-F to focus to the Find text box.\nEnter to commence search.\nEsc to clear.\nShift-Esc to remove focus. +!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.\nShortcut: i\n\nShortcut in Single Editor Tab Mode: Alt-i +!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 images recently saved.\nShortcut: Alt-7 +!FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show images not recently saved.\nShortcut: Alt-6 +!FILEBROWSER_SHOWTRASHHINT;Show content of the trash.\nShortcut: T +!FILEBROWSER_SHOWUNCOLORHINT;Show images without 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_USETEMPLATE;Use template: +!FILEBROWSER_ZOOMINHINT;Increase thumbnail size.\nShortcut: +\n\nShortcut in Single Editor Tab Mode: Alt-+ +!FILEBROWSER_ZOOMOUTHINT;Decrease thumbnail size.\nShortcut: -\n\nShortcut in Single Editor Tab Mode: Alt-- +!GENERAL_ABOUT;About +!GENERAL_AFTER;After +!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\nClick right mouse button 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 (on) or scaled (off) 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;Lab - Lightness +!HISTORY_MSG_15;Lab - Contrast +!HISTORY_MSG_16;Luminance Black +!HISTORY_MSG_17;Luminance Highlight Compr. +!HISTORY_MSG_18;Luminance Shadow Compr. +!HISTORY_MSG_19;'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 Mode 1 +!HISTORY_MSG_42;Tone Curve 2 +!HISTORY_MSG_43;Tone Curve Mode 2 +!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;HL 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;Data specified for resize +!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;Lab - Chromaticity +!HISTORY_MSG_96;'a' Curve +!HISTORY_MSG_97;'b' Curve +!HISTORY_MSG_98;Demosaicing Method +!HISTORY_MSG_99;Hot/Dead pixel filter +!HISTORY_MSG_100;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;Resizing applies to +!HISTORY_MSG_111;Lab - Avoid color shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;Lab - Protection +!HISTORY_MSG_114;DCB Iterations +!HISTORY_MSG_115;False Color Suppression +!HISTORY_MSG_116;DCB Enhancement +!HISTORY_MSG_117;Raw Red CA Correction +!HISTORY_MSG_118;Raw Blue CA Correction +!HISTORY_MSG_119;Line Noise Filter +!HISTORY_MSG_120;Green Equilibration +!HISTORY_MSG_121;Raw Auto CA +!HISTORY_MSG_122;Dark Frame Auto Select +!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 Select +!HISTORY_MSG_128;Flat Field Blur Radius +!HISTORY_MSG_129;Flat Field Blur Type +!HISTORY_MSG_130;Auto Distorion +!HISTORY_MSG_131;Noise Reduction Luma +!HISTORY_MSG_132;Noise Reduction 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;Edges Sharpening +!HISTORY_MSG_147;ES - Luminance Only +!HISTORY_MSG_148;Microcontrast +!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_150;Post Demosaic Artifact/Noise Reduction +!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;'CC' curve +!HISTORY_MSG_169;'CH' curve +!HISTORY_MSG_170;Vib - Curve +!HISTORY_MSG_171;'LC' curve +!HISTORY_MSG_172;Lab - 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 tones protection +!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 pixels +!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;'CL' curve +!HISTORY_MSG_247;'LH' curve +!HISTORY_MSG_248;'HH' curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!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 open in Editor\nShortcut: Shift-F4\n\nTo navigate to the Next image relative to thumbnail selected in File Browser\nShortcut: F4 +!MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the Previous image relative to image open in Editor\nShortcut: Shift-F3 \n\nTo navigate to the Previous image relative to thumbnail selected in File Browser\nShortcut: F3 +!MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronize the File Browser with the Editor to reveal the thumbnail of the currently open image, and clear filters in File Browser \nShortcut: x\n\nAs above, but without clearing filters in File Browser\nShortcut: y\n(Note that thumbnail of the open file 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 the "Preferences" dialog. +!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\ndoesn't exist. Please set a correct path in the Preference window. +!MAIN_MSG_QOVERWRITE;Do you want to overwrite it? +!MAIN_MSG_SETPATHFIRST;You have to set a target path first in Preferences\nin order to use this function! +!MAIN_MSG_WRITEFAILED;Failed to write\n\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_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_TAGGING;Tagging +!MAIN_TAB_TRANSFORM;Transform +!MAIN_TAB_TRANSFORM_TOOLTIP;Shortcut: Alt-t +!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 10-30%\n\nPreview is rendered slower with Focus Mask turned on. +!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_NA;B = n/a +!NAVIGATOR_B_VALUE;B = %1 +!NAVIGATOR_G_NA;G = n/a +!NAVIGATOR_G_VALUE;G = %1 +!NAVIGATOR_H_NA;H = n/a +!NAVIGATOR_H_VALUE;H = %1 +!NAVIGATOR_LAB_A_NA;a = n/a +!NAVIGATOR_LAB_A_VALUE;a = %1 +!NAVIGATOR_LAB_B_NA;b = n/a +!NAVIGATOR_LAB_B_VALUE;b = %1 +!NAVIGATOR_LAB_L_NA;L = n/a +!NAVIGATOR_LAB_L_VALUE;L = %1 +!NAVIGATOR_R_NA;R = n/a +!NAVIGATOR_R_VALUE;R = %1 +!NAVIGATOR_S_NA;S = n/a +!NAVIGATOR_S_VALUE;S = %1 +!NAVIGATOR_V_NA;V = n/a +!NAVIGATOR_V_VALUE;V = %1 +!NAVIGATOR_XY_FULL;Width = %1, Height = %2 +!NAVIGATOR_XY_NA;x = n/a, y = n/a +!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;90° rotation / flipping +!PARTIALPASTE_COLORAPP;CIE Color Appearance Model 2002 +!PARTIALPASTE_COLORGROUP;Color Related Settings +!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_EVERYTHING;Everything +!PARTIALPASTE_EXIFCHANGES;Changes to Exif data +!PARTIALPASTE_EXPOSURE;Exposure +!PARTIALPASTE_FLATFIELDAUTOSELECT;Flat field auto selection +!PARTIALPASTE_FLATFIELDBLURRADIUS;Flat field blur radius +!PARTIALPASTE_FLATFIELDBLURTYPE;Flat field blur type +!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 info +!PARTIALPASTE_LABCURVE;Lab adjustments +!PARTIALPASTE_LENSGROUP;Lens Related Settings +!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_METAICMGROUP;Metadata/Color Management Settings +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_PERSPECTIVE;Perspective +!PARTIALPASTE_PREPROCESS_GREENEQUIL;Green equilibration +!PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Apply hot/dead 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_ALLENHANCE;Post-demosaic artifact/noise reduction +!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_WHITEBALANCE;White balance +!PREFERENCES_ADD;Add +!PREFERENCES_APPLNEXTSTARTUP;restart required +!PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!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_BLINKCLIPPED;Blink clipped areas +!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_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_CMETRICINTENT;Colorimetric intent +!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 scipts 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_DATEFORMATFRAME;Date Format +!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;Date format +!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_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_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_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_GREY;Output device's Yb luminance (%) +!PREFERENCES_GTKTHEME;GTK default +!PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogram in left panel +!PREFERENCES_HLTHRESHOLD;Threshold for clipped highlights +!PREFERENCES_ICCDIR;Directory containing color profiles +!PREFERENCES_IMPROCPARAMS;Default Image Processing Parameters +!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 OS language setting +!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_MONITORICC;Monitor color profile +!PREFERENCES_MULTITABDUALMON;Multiple Editor Tabs Mode (if available on second monitor) +!PREFERENCES_MULTITAB;Multiple Editor Tabs Mode +!PREFERENCES_OUTDIRFOLDERHINT;Put the saved 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 +!PREFERENCES_OVERWRITEOUTPUTFILE;Overwrite existing output files +!PREFERENCES_PANFACTORFRAME;Pan Rate Amplification +!PREFERENCES_PANFACTORLABEL;Factor +!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;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_RGBDTL_LABEL;Max number of threads for Noise Reduction +!PREFERENCES_RGBDTL_TOOLTIP;Noise Reduction requires a baseline of about 128MB RAM for a 10MPix image or 512MB for a 40MPix image, and additionally 128MB RAM per thread. The more threads run in parallel, the faster the computation. Leave the setting at "0" to automatically use as many threads as possible. +!PREFERENCES_SELECTFONT;Select font +!PREFERENCES_SELECTLANG;Select language +!PREFERENCES_SELECTTHEME;Select theme +!PREFERENCES_SET;Set +!PREFERENCES_SHOWBASICEXIF;Show basic Exif info +!PREFERENCES_SHOWDATETIME;Show date and time +!PREFERENCES_SHOWEXPOSURECOMPENSATION;Append exposure compensation +!PREFERENCES_SHOWPROFILESELECTOR;Show processing profile selector +!PREFERENCES_SHTHRESHOLD;Threshold for clipped shadows +!PREFERENCES_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs +!PREFERENCES_SINGLETAB;Single Editor Tab Mode +!PREFERENCES_SLIMUI;Slim interface +!PREFERENCES_SND_BATCHQUEUEDONE;Queue processing done +!PREFERENCES_SND_HELP;Either enter filepath or nothing (for no sound).\nOn Windows use "SystemDefault", "SystemAsterisk" etc. for system sounds.\nOn Linux use "complete", "window-attention" etc. for system sounds. +!PREFERENCES_SND_LNGEDITPROCDONE;Editor processing done +!PREFERENCES_SND_TRESHOLDSECS;after secs +!PREFERENCES_SQUAREDETAILWINDOW;Square detail window (faster) +!PREFERENCES_STARTUPIMDIR;Image Directory at Startup +!PREFERENCES_TAB_BROWSER;File Browser +!PREFERENCES_TAB_COLORMGR;Color Management +!PREFERENCES_TAB_GENERAL;General +!PREFERENCES_TAB_IMPROC;Image Processing +!PREFERENCES_TAB_PERFORMANCE;Performance +!PREFERENCES_TAB_SOUND;Sounds +!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_WORKFLOW;Layout +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_FILEDLGFILTERANY;Any files +!PROFILEPANEL_FILEDLGFILTERPP;Processing profiles +!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_JPGFILTER;JPEG files +!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_TIFFFILTER;TIFF files +!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_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing channel-mixer +!TP_BWMIX_BLUE;Blue +!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;Modify luminance in function of hue\nPay attention to extreme values that may cause artifacts +!TP_BWMIX_CYAN;Cyan +!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 simulate shots taken with a colored filter placed in front of the lens. Colored filters reduce transmission of specific range of colors and correspondingly affect their lightness. E.g. a Red filter darkens Blue skies. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_BLUE;Blue Channel +!TP_BWMIX_GAM_GREEN;Green Channel +!TP_BWMIX_GAM_RED;Red Channel +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each channel RGB +!TP_BWMIX_GREEN;Green +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MAGENTA;Magenta +!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 (filter, channel-mixer) to default +!TP_BWMIX_ORANGE;Orange +!TP_BWMIX_PURPLE;Purple +!TP_BWMIX_RED;Red +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all of the mixer options\nTotal displays the sum of RGB values actually applied:\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 (films, landscape, ...) or manual settings of channel-mixer +!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;Channel-Mixer absolute RGB +!TP_BWMIX_SET_RGBREL;Channel-Mixer relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Channel-Mixer absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Channel-Mixer 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_BWMIX_YELLOW;Yellow +!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.\nShortcut: [\n\nShortcut in Single Editor Tab: Alt-[ +!TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotate right.\nShortcut: ]\n\nShortcut in Single Editor Tab: Alt-] +!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) RT 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.\n 0=no effect 1=median 2=gaussian.\n\nThese artifacts are due to limitations of CIECAM02. Alternatively, adjust the image to avoid very dark shadows. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from Lab and RGB brightness +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from Lab and RGB colorfulness +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from Lab and RGB saturation +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from Lab 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 Lab and RGB contrast +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from Lab and RGB contrast +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L (Lab) 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 (Lab) 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 Lab values before CIECAM02 adjustments +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RT 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 (Lab) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in Lab 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 Lab and RGB lightness +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model\n\nWB [RT] + [output]:\nRT's white balance is used for the scene, CIECAM02 is set to D50, the output device's white balance is set in Preferences > Color Management\n\nWB [RT+CAT02] + [output]:\nRT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences +!TP_COLORAPP_RSTPRO;Red & skin tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin tones protection (sliders and curves) +!TP_COLORAPP_SHARPCIE;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe with Q/C +!TP_COLORAPP_SHARPCIE_TOOLTIP;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe will use CIECAM02 if enabled. +!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;Change tones and colors to take into account the viewing conditions of the output device\n\nAverage:\nAverage light environment (standard)\nThe image will not change\n\nDim:\nDim environment (TV)\nThe image will become slighty dark\n\nDark:\nDark environment (projector)\nThe image will become more dark\n\nExtremly Dark:\nExtremly dark environment (cutsheet)\nThe image will become very dark +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if source 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 Lab 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_CROP_FIXRATIO;Fix ratio: +!TP_CROP_GTDIAGONALS;Rule of Diagonals +!TP_CROP_GTEPASSPORT;Biometric Passport +!TP_CROP_GTFRAME;Frame +!TP_CROP_GTGRID;Grid +!TP_CROP_GTHARMMEANS1;Harmonic Means 1 +!TP_CROP_GTHARMMEANS2;Harmonic Means 2 +!TP_CROP_GTHARMMEANS3;Harmonic Means 3 +!TP_CROP_GTHARMMEANS4;Harmonic Means 4 +!TP_CROP_GTNONE;None +!TP_CROP_GTRULETHIRDS;Rule of Thirds +!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_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_CHROMA;Chrominance - Master +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on gamma of the input color profile. Gamma of sRGB is assumed, thus if input image is in color profile of a different gamma, luminance noise reduction will vary. +!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_LAB;Lab +!TP_DIRPYRDENOISE_LDETAIL;Luminance Detail +!TP_DIRPYRDENOISE_LUMA;Luminance +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or Lab methods can be used.\n\nFor non-raw images Lab method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_PERF;RGB mode (raw images) +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGB;RGB +!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_THRESHOLD;Threshold +!TP_DISTORTION_AMOUNT;Amount +!TP_DISTORTION_AUTO;Auto Distortion Correction +!TP_DISTORTION_AUTO_TIP;(Exprimental) 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_LABEL;Tone Mapping +!TP_EPD_REWEIGHTINGITERATES;Reweighting Iterates +!TP_EPD_SCALE;Scale +!TP_EPD_STRENGTH;Strength +!TP_EPD_TOOLTIP;Tone mapping is possible via Lab mode (standard) and CIECAM02 mode.\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_EXPOSCORR_LABEL;Raw White & Black Points +!TP_EXPOSURE_AUTOLEVELS;Auto Levels +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggle execution of auto levels to automatically set parameter values based on image analysis\nEnable 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 level's 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 following section of the manual to learn how to achieve the best results with double curves:\nThe Toolbox > Exposure Tab > Exposure Panel > Tone Curve +!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_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!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_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 effect of this tool or some of its sub-component is only visible at 1:1 preview scale. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Rotation anchor point X: -100=left edge, 0=center, +100=right edge +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Rotation anchor point Y: -100=top edge, 0=center, +100=bottom edge +!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 automatic exposure +!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 blown 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_FILEDLGFILTERANY;Any files +!TP_ICM_FILEDLGFILTERICM;Color profiles +!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 simple color matrix by dcraw, enhanced RawTherapee version (whichever is available based on camera model) or embedded in 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. Use 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_TOOLTIP;Save the linear TIFF image before the input profile is applied. Result can be used for calibration purposes, 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;Lab 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;Can be used with the Chromaticity slider and the CC curve. +!TP_LENSGEOM_AUTOCROP;Auto Crop +!TP_LENSGEOM_FILL;Auto fill +!TP_LENSGEOM_LABEL;Lens / Geometry +!TP_LENSPROFILE_FILEDLGFILTERLCP;Lens correction files +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;CA Correction +!TP_LENSPROFILE_USEDIST;Distortion correction +!TP_LENSPROFILE_USEVIGN;Vignetting correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset 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: 0=corners only, 50=halfway to center, 100=to center +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness: 0=rectangle, 50=fitted ellipse, 100=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. Higher = more, lower = less. +!TP_PREPROCESS_GREENEQUIL;Green Equilibration +!TP_PREPROCESS_HOTDEADPIXFILT;Hot/Dead pixel filter +!TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Try to suppress hot and dead 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_BLACKONE;Black Level: Red +!TP_RAWEXPOS_BLACKS;Black Levels +!TP_RAWEXPOS_BLACKTHREE;Black Level: Green 2 +!TP_RAWEXPOS_BLACKTWO;Black Level: Blue +!TP_RAWEXPOS_BLACKZERO;Black Level: Green 1 (lead) +!TP_RAWEXPOS_LINEAR;White Point Correction +!TP_RAWEXPOS_PRESER;Highlight Preservation +!TP_RAWEXPOS_TWOGREEN;Link greens +!TP_RAW_ALLENHANCE;Post-Demosaic Artifact/Noise Reduction +!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 +!TP_RAW_FALSECOLOR;False Color Suppression Steps +!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_RESIZE_APPLIESTO;Applies to: +!TP_RESIZE_BICUBICSF;Bicubic (Softer) +!TP_RESIZE_BICUBICSH;Bicubic (Sharper) +!TP_RESIZE_BICUBIC;Bicubic +!TP_RESIZE_BILINEAR;Bilinear +!TP_RESIZE_CROPPEDAREA;Cropped Area +!TP_RESIZE_FITBOX;Bounding Box +!TP_RESIZE_FULLIMAGE;Full Image +!TP_RESIZE_HEIGHT;Height +!TP_RESIZE_H;H: +!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;W: +!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;Tonal Width for Highlights +!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;Tonal Width for Shadows +!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 used 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_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_ZOOMFITSCREEN;Fit 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..805032241 --- /dev/null +++ b/rtdata/languages/Espanol @@ -0,0 +1,1562 @@ +#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 con Gradiente (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 Dim: Luz tenue +#27 Feather: Difuminado +#28 Illuminant: Iluminante +#29 Lightness: Claridad +#30 Luminance: Luminancia (*) +#31 Luminosity: Luminosidad +#32 Mapping: Mapeo (*) +#33 Sharpening: Enfoque +#34 Slider: Control deslizante +#35 Tone Curve: Curva tonal +#36 Vibrance: Vibranza +#37 +#38 (*) Término incluido en diccionario RAE +#39 (**) Término no incluido en diccionario RAE +#40 +#41 Términos conservados en Inglés por no tener traducción breve +#42 al español en el sentido usado por RT/fotografía digital +#43 Dark Frame +#44 ICM (Image Color Management) +#45 Gamut +#46 Gamma +#47 Raw +#48 +#49 2008-01-15 keenonkites, first translation +#50 2008-03-03 Ioritz Ibarguren, corrections +#51 2008-04-05 keenonkites, completed for 2.4m1 +#52 2008-04-09 Ramon, partly corrected (part of 2.3) +#53 2008-04-29 Ramon, small correction +#54 2008-06-09 Ramon, Adaptions regarding 2.4m1 and others +#55 2008-09-20 keenonkites, first version for 2.4m2 +#56 2008-12-19 keenonkites, first version for 2.4beta4 +#57 2010-12-07 rickydh, some translations of untranslated keys for 3.0 alpha1 +#58 2011-12-25 plores, translation improvement, translation of untranslated strings +#59 2013-01-03 OdeLama, translation of untranslated strings + +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_FILEDLGFILTERANY;Cualquier archivo +CURVEEDITOR_FILEDLGFILTERCURVE;Archivos de curvas +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: +EDITWINDOW_TITLE;Edición de imagen +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;Reiniciar todos los atributos a los valores originales +EXIFPANEL_RESETALL;Reiniciar todo +EXIFPANEL_RESETHINT;Reiniciar atributos seleccionados a los valores originales +EXIFPANEL_RESET;Reiniciar +EXIFPANEL_SUBDIRECTORY;Subcarpeta +EXPORT_BYPASS_ALL;Seleccionar / deseleccionar todo +EXPORT_BYPASS_COLORDENOISE;Saltar Reducción de ruido de color +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_LUMADENOISE;Saltar Reducción de ruido de luminancia +EXPORT_BYPASS_RAW_ALL_ENHANCE;Saltar Reducción de Ruido/artefactos post-interpolado +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] Dark Frame +EXPORT_BYPASS_RAW_FF;Saltar [raw] Campo plano +EXPORT_BYPASS_RAW_GREENTHRESH;Saltar [raw] Equilibrado del verde +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 +EXPORT_RESIZEMETHOD;Método de cambio de tamaño +EXTPROGTARGET_1;Raw +EXTPROGTARGET_2;procesada en cola +FILEBROWSER_ADDDELTEMPLATE;Añadir/Borrar plantillas... +FILEBROWSER_APPLYPROFILE;Aplicar perfil +FILEBROWSER_APPLYPROFILE_PARTIAL;Aplicar perfil (parcial) +FILEBROWSER_AUTODARKFRAME;Auto Dark Frame +FILEBROWSER_AUTOFLATFIELD;Auto Campo plano +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;Dark Frame +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 Dark Frames +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_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_POPUPOPEN;Abrir +FILEBROWSER_POPUPPROCESSFAST;Poner en la cola (exportación rápida) +FILEBROWSER_POPUPPROCESS;Poner en la cola +FILEBROWSER_POPUPPROFILEOPERATIONS;Operaciones con perfiles +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 Dark Frame... +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: 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 procesamiento de imágenes en la cola +FILEBROWSER_STARTPROCESSING;Iniciar procesamiento +FILEBROWSER_STOPPROCESSINGHINT;Parar procesamiento de imágenes en la cola +FILEBROWSER_STOPPROCESSING;Parar procesamiento +FILEBROWSER_THUMBSIZE;Tamaño miniatura +FILEBROWSER_TOOLTIP_STOPPROCESSING;Iniciar automáticamente el procesamiento cuando llega un nuevo trabajo +FILEBROWSER_UNRANK_TOOLTIP;Sin Rango\nAtajoShift - 0 +FILEBROWSER_USETEMPLATE;Utilizar plantilla: +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 de 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;Auto relleno +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. Dark Frame +HISTORY_MSG_123;Archivo Dark Frame +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 'CH' +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 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_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;Reiniciar 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;Reiniciar a los ajustes predeterminados del perfil. +IPTCPANEL_RESET;Reiniciar +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_SAVEAS;Como... +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_TAGGING;Etiquetado +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_B_NA;B = n/a +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_LAB_A_NA;A = n/a +NAVIGATOR_LAB_A_VALUE;A = %1 +NAVIGATOR_LAB_B_NA;B = n/a +NAVIGATOR_LAB_B_VALUE;B = %1 +NAVIGATOR_LAB_L_NA;L = n/a +NAVIGATOR_LAB_L_VALUE;L = %1 +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_V_VALUE;V = %1 +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_COMMONTRANSFORMPARAMS;Auto relleno +PARTIALPASTE_COMPOSITIONGROUP;Ajustes de composición +PARTIALPASTE_CROP;Recortar +PARTIALPASTE_DARKFRAMEAUTOSELECT;Auto Selección de Dark Frame +PARTIALPASTE_DARKFRAMEFILE;Archivo de Dark Frame +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_FLATFIELDAUTOSELECT;Auto Selección de campo plano +PARTIALPASTE_FLATFIELDBLURRADIUS;Radio de difuminado de campo plano +PARTIALPASTE_FLATFIELDBLURTYPE;Tipo de difuminado de campo plano +PARTIALPASTE_FLATFIELDFILE;Archivo de campo plano +PARTIALPASTE_GRADIENTSHARPEN;Nitidez por gradiente (bordes) +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_LUMACURVE;Curva de luminancia +PARTIALPASTE_METAICMGROUP;Ajustes de metadatos/Gestión de color +PARTIALPASTE_MICROCONTRAST;Microcontraste +PARTIALPASTE_PCVIGNETTE;Filtro quitar viñeteado +PARTIALPASTE_PERSPECTIVE;Perspectiva +PARTIALPASTE_PREPROCESS_GREENEQUIL;Equilibrio del verde +PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Filtrar píxel caliente/muerto +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_ALLENHANCE;Aplicar reducción de ruido/artefactos post-interpolado +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 +POPUPBUTTON_SELECTOPTIONHINT;RMB para cambiar opción +PREFERENCES_ADD;Añadir +PREFERENCES_APPLNEXTSTARTUP;aplicado al próximo arranque +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_BLINKCLIPPED;Parpadear áreas cortadas +PREFERENCES_CABLUE;Correcc. manual aberr. cromát. Azul +PREFERENCES_CACHECLEARALL;Borrar todo +PREFERENCES_CACHECLEARPROFILES;Borrar perfiles +PREFERENCES_CACHECLEARTHUMBS;Borrar miniaturas +PREFERENCES_CACHEFORMAT1;Propio (más rápido y mejor calidad) +PREFERENCES_CACHEFORMAT2;JPEG (menos consumo de disco duro) +PREFERENCES_CACHEMAXENTRIES;Cantidad máxima de entradas en la memoria intermedia +PREFERENCES_CACHEOPTS;Opciones de memoria intermedia +PREFERENCES_CACHETHUMBFORM;Formato de las miniaturas +PREFERENCES_CACHETHUMBHEIGHT;Altura máxima de las miniaturas +PREFERENCES_CACORRECTION;Aplicar autocorrección aberr. cromát. +PREFERENCES_CARED;Correcc. manual aberr. cromát. Rojo +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_CLEARDLG_LINE1;Borrando memoria intermedia +PREFERENCES_CLEARDLG_LINE2;Puede durar unos segundos. +PREFERENCES_CLEARDLG_TITLE;Aguardar, por favor +PREFERENCES_CLIPPINGIND;Indicación de recortes +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;Dark Frame +PREFERENCES_DATEFORMATFRAME;Formato de fecha +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_DCBENHANCE;Aplicar paso mejora DCB +PREFERENCES_DCBITERATIONS;Número iteraciones DCB +PREFERENCES_DEFAULTLANG;Idioma predeterminado +PREFERENCES_DEFAULTTHEME;Tema predeterminado +PREFERENCES_DIRDARKFRAMES;Carpeta de Dark Frames +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_DMETHOD;Método +PREFERENCES_EDITORCMDLINE;Otra línea de comando +PREFERENCES_EDITORLAYOUT;Disposición del editor +PREFERENCES_EXPOS;Exposición antes de interpolación:\ncorrección (lineal) +PREFERENCES_EXTERNALEDITOR;Editor externo +PREFERENCES_FALSECOLOR;Pasos de supresión de colores falsos +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_FLATFIELDAUTOSELECT;Selección automática de campo plano +PREFERENCES_FLATFIELDBLURRADIUS;Radio de difuminado de campo plano +PREFERENCES_FLATFIELDBLURTYPE;Tipo de difuminado de campo plano +PREFERENCES_FLATFIELDFILE;Archivo de campo plano +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_GREENEQUIL;Equilibrado del verde +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_GTKTHEME;Tema GTK predeterminado +PREFERENCES_HISTOGRAMPOSITIONLEFT;Histograma en panel izquierdo +PREFERENCES_HLTHRESHOLD;Umbral de luces altas cortadas +PREFERENCES_HOTDEADPIXFILT;Aplicar filtro de píxel dañado +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 configuración de idioma del SO +PREFERENCES_LINEDENOISE;Filtro de ruido de línea +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_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_PANFACTORFRAME;Aceleración del paneo +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_PRESER;Exposición antes de interpolación:\npreservar luces altas (EV) +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_SHOWPROFILESELECTOR;Mostrar selector de perfiles de procesamiento +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_SQUAREDETAILWINDOW;Ventana de detalle cuadrada (más rápido) +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 establecido en el dispositivo de salida (monitor, TV, proyector, etc.) +PREFERENCES_WORKFLOW;Disposición +PROFILEPANEL_COPYPPASTE;Parámetros a copiar +PROFILEPANEL_FILEDLGFILTERANY;Cualquier archivo +PROFILEPANEL_FILEDLGFILTERPP;Perfiles de procesamiento +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_LOADING;Abriendo archivo... +PROGRESSDLG_PROCESSING;Procesando imagen... +PROGRESSDLG_PROFILECHANGEDINBROWSER;Perfil de procesamiento cambiado en explorador +PROGRESSDLG_SAVING;Guardando archivo... +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_JPGFILTER;Archivos 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_TIFFFILTER;Archivos TIFF +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_AUTOCH;Auto +TP_BWMIX_AUTOCH_TIP;Calcular valores óptimos para el Mezclador de Canales +TP_BWMIX_BLUE;Azul +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_CYAN;Cian +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_BLUE;Canal Azul +TP_BWMIX_GAM_GREEN;Canal Verde +TP_BWMIX_GAM_RED;Canal Rojo +TP_BWMIX_GAM_TOOLTIP;Corrige la Gamma de cada canal RGB +TP_BWMIX_GREEN;Verde +TP_BWMIX_LABEL;Blanco y Negro +TP_BWMIX_MAGENTA;Magenta +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_ORANGE;Naranja +TP_BWMIX_PURPLE;Púrpura +TP_BWMIX_RED;Rojo +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;Mezclador de canales RGB Absoluto +TP_BWMIX_SET_RGBREL;Mezclador de canales RGB Relativo +TP_BWMIX_SET_ROYGCBPMABS;Mezclador de canales RNAmVCAzPM Absoluto +TP_BWMIX_SET_ROYGCBPMREL;Mezclador de canales RNAmVCAzPM Relativo +TP_BWMIX_TCMODE_FILMLIKE;B&N emulando 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_BWMIX_YELLOW;Amarillo +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_CLARITY_LABEL;Claridad y nitidez +TP_CLARITY_MATRIX;Matriz 3x3 en lugar de 5x5 +TP_CLARITY_MICRO;Microcontraste (textura) +TP_CLARITY_PASSES;Pasos de gradiente +TP_CLARITY_SHARPEN;Nitidez por gradiente (bordes) +TP_CLARITY_STRENGTH;Intensidad de gradiente +TP_CLARITY_THREE;Sólo luminancia +TP_COARSETRAF_DEGREE;Grados: +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;Adaptación a la 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=No effect 1=Mediana 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;Muestra en las curvas 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;Protección de tonos rojos y color piel (curvas y 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_COLORBOOST_ACHANNEL;canal "a" +TP_COLORBOOST_AMOUNT;Cantidad +TP_COLORBOOST_AVOIDCOLORCLIP;Evitar recorte de colores +TP_COLORBOOST_BCHANNEL;canal "b" +TP_COLORBOOST_CHAB;a & b +TP_COLORBOOST_CHANNEL;Canal +TP_COLORBOOST_CHSEPARATE;independiente +TP_COLORBOOST_ENABLESATLIMITER;Activar limitador de saturación +TP_COLORBOOST_LABEL;Aumento de color +TP_COLORBOOST_SATLIMIT;Límite de saturación +TP_COLORDENOISE_EDGESENSITIVE;Sensible a bordes +TP_COLORDENOISE_EDGETOLERANCE;Tolerancia de bordes +TP_COLORDENOISE_LABEL;Reducción de ruido de color +TP_COLORDENOISE_RADIUS;Radio +TP_COLORSHIFT_BLUEYELLOW;Azul-Amarillo +TP_COLORSHIFT_GREENMAGENTA;Verde-Magenta +TP_COLORSHIFT_LABEL;Desplazamiento de colores +TP_CROP_DPI;DPI= +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_GTHARMMEANS1;Forma armónica 1 +TP_CROP_GTHARMMEANS2;Forma armónica 2 +TP_CROP_GTHARMMEANS3;Forma armónica 3 +TP_CROP_GTHARMMEANS4;Forma armónica 4 +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;Dark Frame +TP_DEFRINGE_LABEL;Quitar borde púrpura +TP_DEFRINGE_RADIUS;Radio +TP_DEFRINGE_THRESHOLD;Umbral +TP_DETAIL_AMOUNT;Cantidad +TP_DIRPYRDENOISE_BLUE;Crominancia - Azul-Amarillo +TP_DIRPYRDENOISE_CHROMA;Crominancia - Maestra +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_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_LDETAIL;Detalle en luminancia +TP_DIRPYRDENOISE_LUMA;Luminancia +TP_DIRPYRDENOISE_METHOD;Método +TP_DIRPYRDENOISE_METHOD_TOOLTIP;Para imágenes Raw puede usarse tanto el método RGB como el Lab.\n\nPara imágenes no Raw el método Lab será usado, ignorando el método seleccionado. +TP_DIRPYRDENOISE_PERF;Modo RGB (imagen raw) +TP_DIRPYRDENOISE_RED;Crominancia - Rojo-Verde +TP_DIRPYRDENOISE_RGB;RGB +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_THRESHOLD;Umbral +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_EQUALIZER_CONTRAST_MINUS;Contraste- +TP_EQUALIZER_CONTRAST_PLUS;Contraste+ +TP_EQUALIZER_FINEST;muy fino +TP_EQUALIZER_LABEL;Ecualizador de wavelets +TP_EQUALIZER_LARGEST;muy grueso +TP_EQUALIZER_NEUTRAL;Neutro +TP_EXPOSCORR_LABEL;Puntos Blanco y Negro (Raw) +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;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;Comp. de exposición +TP_EXPOSURE_LABEL;Exposición +TP_EXPOSURE_SATURATION;Saturación +TP_EXPOSURE_TCMODE_FILMLIKE;Similar a la 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_VALBLENDING;Canal de valor +TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Estándar ponderado +TP_EXPO_AFTER; Después de la interpolación (antes de la conversión RGB) +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_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\n0=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 con 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_HSVEQUALIZER1;Rojo +TP_HSVEQUALIZER2;Amarillo +TP_HSVEQUALIZER3;Lima +TP_HSVEQUALIZER4;Verde +TP_HSVEQUALIZER5;Aqua +TP_HSVEQUALIZER6;Azul +TP_HSVEQUALIZER7;Púrpura +TP_HSVEQUALIZER8;Magenta +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_FILEDLGFILTERANY;Cualquier archivo +TP_ICM_FILEDLGFILTERICM;Perfiles de color +TP_ICM_GAMMABEFOREINPUT;El perfil aplica gamma +TP_ICM_INPUTCAMERAICC;Perfil de la cámara (auto-matched) +TP_ICM_INPUTCAMERAICC_TOOLTIP;Usa perfil de color de entrada específico de la cámara de 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_PREFERREDPROFILE;Perfil DCP preferido +TP_ICM_PREFERREDPROFILE_1;Luz de día +TP_ICM_PREFERREDPROFILE_2;Tungsteno +TP_ICM_PREFERREDPROFILE_3;Fluorescente +TP_ICM_PREFERREDPROFILE_4;Flash +TP_ICM_SAVEREFERENCEDLGLABEL;Guardar imagen de referencia para perfilado +TP_ICM_SAVEREFERENCE;Guardar imagen de referencia para el perfilado +TP_ICM_TONECURVE;Usar la curva de tonal DCP incrustada. Este ajuste es posible solo si el DCP seleccionado contiene una curva tonal. +TP_ICM_TONECURVE_TOOLTIP;Activa el uso de las curvas de tono que pueden contener los perfiles DCP. +TP_ICM_WORKINGPROFILE;Perfil de trabajo +TP_IMPULSEDENOISE_LABEL;Impulsar Reducc. ruido +TP_IMPULSEDENOISE_THRESH;Umbral +TP_LABCURVE_AVOIDCOLORCLIP;Evitar recorte de colores +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_BWTONING;Mapeo de tonos B/N +TP_LABCURVE_BWTONING_TIP;Con la opción Mapeo de tonos B/N activada, la cromaticidad Lab y las curvas Cc y Ch no tienen efecto.\nEl mapeo de tonos puede conseguirse usando las curvas a y b +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_CCL_TOOLTIP;Luminancia de acuerdo con Cromaticidad - Tonos de piel y también Rojo -Amarillo - Azul - Verde +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_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_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_ENABLESATLIMITER;Activar limitador de saturación +TP_LABCURVE_LABEL;Ajustes Lab +TP_LABCURVE_LCREDSK;Restringe LC a tonos rojos y piel +TP_LABCURVE_LCREDSK_TIP;Si se activa, '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_LABCURVE_SATLIMIT;Límite de saturación +TP_LABCURVE_SATURATION;Saturación +TP_LENSGEOM_AUTOCROP;Auto recorte +TP_LENSGEOM_FILL;Auto relleno +TP_LENSGEOM_LABEL;Lente / Geometría +TP_LENSPROFILE_FILEDLGFILTERLCP;Archivos de correción de lente +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_LUMACURVE_BLACKLEVEL;Negro +TP_LUMACURVE_BRIGHTNESS;Brillo +TP_LUMACURVE_COMPRHIGHLIGHTS;Compresión de luces altas +TP_LUMACURVE_COMPRSHADOWS;Compresión de sombras +TP_LUMACURVE_CONTRAST;Contraste +TP_LUMACURVE_CURVEEDITOR;Curva de luminancia +TP_LUMACURVE_LABEL;Curva de luminancia +TP_MLMICRO_STRENGTH;Intensidad +TP_MLMICRO_UNIFORMITY;Uniformidad +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\n\nbajo = menos. +TP_PREPROCESS_DARKFRAME;Imagen en oscuridad +TP_PREPROCESS_DFAUTOSELECT;Selección automática +TP_PREPROCESS_FLATFIELDAUTOSELECT;Selección automática de campo plano +TP_PREPROCESS_FLATFIELDBLURRADIUS;Radio de difuminado de campo plano +TP_PREPROCESS_FLATFIELDBLURTYPE;Tipo de difuminado de campo plano +TP_PREPROCESS_FLATFIELDFILE;Archivo de campo plano +TP_PREPROCESS_GREENEQUIL;Equilibrado del verde +TP_PREPROCESS_HOTDEADPIXFILT;Aplicar filtro de píxel dañado +TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Intenta eliminar píxeles calientes o muertos +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_BLACKONE;Nivel de negro: Rojo +TP_RAWEXPOS_BLACKS;Niveles de negro +TP_RAWEXPOS_BLACKTHREE;Nivel de negro: Verde 2 +TP_RAWEXPOS_BLACKTWO;Nivel de negro: Azul +TP_RAWEXPOS_BLACKZERO;Nivel de negro: Verde 1 (líder) +TP_RAWEXPOS_LINEAR;Corrección de punto blanco +TP_RAWEXPOS_PRESER;Preservación de Luces Altas +TP_RAWEXPOS_TWOGREEN;Vincular verdes +TP_RAWPANEL_DEMOSAICING;Desmosaicado +TP_RAWPANEL_PREPROCESSING;Preprocesado +TP_RAW_ALLENHANCE;Aplicar reducción de ruido/artefactos post-desmosaicado +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_RESIZE_APPLIESTO;Aplica a: +TP_RESIZE_BICUBICSF;Bicúbica (más suave) +TP_RESIZE_BICUBICSH;Bicúbica (más enfocado) +TP_RESIZE_BICUBIC;Bicúbica +TP_RESIZE_BILINEAR;Bilineal +TP_RESIZE_CROPPEDAREA;Área recortada +TP_RESIZE_DOWNSCALEB;Reducir resolución (más calidad) +TP_RESIZE_DOWNSCALEF;Reducir resolución (más velocidad) +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_AUTOCROP;Recorte automático +TP_ROTATE_DEGREE;Grados +TP_ROTATE_FILL;Llenar +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 eq. bl. +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. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. Result can be used for calibration purposes, generation of a camera profile. diff --git a/rtdata/languages/Euskara b/rtdata/languages/Euskara new file mode 100644 index 000000000..9aef48c5a --- /dev/null +++ b/rtdata/languages/Euskara @@ -0,0 +1,1441 @@ +#01 2008-03-03 Ioritz Ibarguren + +ADJUSTER_RESET_TO_DEFAULT;Hasierako balioetara itzuli +CURVEEDITOR_FILEDLGFILTERANY;Artxibo guztiak +CURVEEDITOR_FILEDLGFILTERCURVE;Kurba artxiboak +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 +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_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_SAVEAS;Honela... +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_TAGGING;Tagging +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_LUMACURVE;Luminance curve +PARTIALPASTE_METAICMGROUP;Metadata/ICM settings +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_BLINKCLIPPED;Moztutako guneak keinuka +PREFERENCES_CACHECLEARALL;Clear All +PREFERENCES_CACHECLEARPROFILES;Clear Profiles +PREFERENCES_CACHECLEARTHUMBS;Clear Thumbnails +PREFERENCES_CACHEFORMAT1;Proprietary (faster and better quality) +PREFERENCES_CACHEFORMAT2;JPEG (smaller disk footprint) +PREFERENCES_CACHEMAXENTRIES;Maximal Number of Cache Entries +PREFERENCES_CACHEOPTS;Cache Options +PREFERENCES_CACHETHUMBFORM;Cache Thumbnail Format +PREFERENCES_CACHETHUMBHEIGHT;Maximal Thumbnail Height +PREFERENCES_CLEARDLG_LINE1;Clearing cache +PREFERENCES_CLEARDLG_LINE2;This may take a few seconds. +PREFERENCES_CLEARDLG_TITLE;Please wait +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_GTKTHEME;GTK default +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_FILEDLGFILTERANY;Artxibo guztiak +PROFILEPANEL_FILEDLGFILTERPP;Prozesu profilak +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... +PROGRESSDLG_LOADING;Loading file... +PROGRESSDLG_PROCESSING;Processing image... +PROGRESSDLG_SAVING;Saving file... +QINFO_ISO;ISO +QINFO_NOEXIF;Ez dago EXIF daturik. +SAVEDLG_FILEFORMAT;Artxiboaren formatua +SAVEDLG_JPEGQUAL;JPEG kalitatea +SAVEDLG_JPGFILTER;JPEG artxiboak +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 +SAVEDLG_TIFFFILTER;TIFF artxiboak +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_DEGREE;Graduak: +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_COLORBOOST_ACHANNEL;"a" kanala +TP_COLORBOOST_AMOUNT;Kopurua +TP_COLORBOOST_AVOIDCOLORCLIP;Kolore mozketa ekidin +TP_COLORBOOST_BCHANNEL;"b" kanala +TP_COLORBOOST_CHANNEL;Kanala +TP_COLORBOOST_CHSEPARATE;bananduak +TP_COLORBOOST_ENABLESATLIMITER;Saturazio muga gaitu +TP_COLORBOOST_LABEL;Koloreak jaso +TP_COLORBOOST_SATLIMIT;Saturazio muga +TP_COLORDENOISE_EDGESENSITIVE;Ertzetara sentikorra +TP_COLORDENOISE_EDGETOLERANCE;Ertz tolerantzia +TP_COLORDENOISE_LABEL;Kolore zarata murrizketa +TP_COLORDENOISE_RADIUS;Erradioa +TP_COLORSHIFT_BLUEYELLOW;Urdin-Horia +TP_COLORSHIFT_GREENMAGENTA;Berde-Magenta +TP_COLORSHIFT_LABEL;Kolore aldaketa +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;Erlazio finkoa: +TP_CROP_GTDIAGONALS;Diagonalen erregela +TP_CROP_GTHARMMEANS1;Bataz besteko armonikoa 1 +TP_CROP_GTHARMMEANS2;Bataz besteko armonikoa 2 +TP_CROP_GTHARMMEANS3;Bataz besteko armonikoa 3 +TP_CROP_GTHARMMEANS4;Bataz besteko armonikoa 4 +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_FILEDLGFILTERANY;Artxibo guztiak +TP_ICM_FILEDLGFILTERICM;ICC profilen artxiboak +TP_ICM_GAMMABEFOREINPUT;Profile applies Gamma +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_LUMACURVE_BLACKLEVEL;Beltza +TP_LUMACURVE_BRIGHTNESS;Distira +TP_LUMACURVE_COMPRHIGHLIGHTS;Argi konpresioa +TP_LUMACURVE_COMPRSHADOWS;Itzal konpresioa +TP_LUMACURVE_CONTRAST;Kontrastea +TP_LUMACURVE_CURVEEDITOR;Argitasun kurba +TP_LUMACURVE_LABEL;Argitasun kurba +TP_RAW_DMETHOD;Metodoa +TP_RAW_FALSECOLOR;Okerreko kolore ezabaketa atalak +TP_RESIZE_BICUBICSF;Bikubikoa (Biguna) +TP_RESIZE_BICUBICSH;Bikubikoa (Fokatua) +TP_RESIZE_BICUBIC;Bikubikoa +TP_RESIZE_BILINEAR;Bilineala +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_AUTOCROP;Auto mozketa +TP_ROTATE_DEGREE;Angelua +TP_ROTATE_FILL;Bete +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_CURVES;Curves +!CURVEEDITOR_CURVE;Curve +!CURVEEDITOR_CUSTOM;Custom +!CURVEEDITOR_DARKS;Darks +!CURVEEDITOR_HIGHLIGHTS;Highlights +!CURVEEDITOR_LIGHTS;Lights +!CURVEEDITOR_MINMAXCPOINTS;Minima/Maxima control points +!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 +!EXIFFILTER_EXPOSURECOMPENSATION;Exposure Compensation (EV) +!EXIFFILTER_FILETYPE;File Type +!EXIFFILTER_METADATAFILTER;Enable Metadata Filters +!EXPORT_BYPASS_ALL;Select / Unselect All +!EXPORT_BYPASS_COLORDENOISE;Bypass Color denoise +!EXPORT_BYPASS_DEFRINGE;Bypass Defringe +!EXPORT_BYPASS_DIRPYRDENOISE;Bypass Noise Reduction +!EXPORT_BYPASS_DIRPYREQUALIZER;Bypass Contrast by Detail Levels +!EXPORT_BYPASS_LUMADENOISE;Bypass Luma denoise +!EXPORT_BYPASS_RAW_ALL_ENHANCE;Bypass Post Demosaic Artifact/Noise Reduction +!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 +!EXPORT_RESIZEMETHOD;Resize 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.\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\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_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_POPUPRANK;Rank +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!FILEBROWSER_QUERYHINT;Type a partial filename to search for or a comma-separated list.\nE.g. 1001,1004,1199 \n\nCtrl-F to focus to the Find text box.\nEnter to commence search.\nEsc to clear.\nShift-Esc to remove focus. +!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.\nShortcut: i\n\nShortcut in Single Editor Tab Mode: Alt-i +!FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show images recently saved.\nShortcut: Alt-7 +!FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show images not recently saved.\nShortcut: Alt-6 +!FILEBROWSER_SHOWUNCOLORHINT;Show images without Color label.\nShortcut: Alt-0 +!FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +!FILEBROWSER_UNRANK_TOOLTIP;Unrank\nShortcut: Shift-0 +!FILEBROWSER_USETEMPLATE;Use template: +!GENERAL_AFTER;After +!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\nClick right mouse button on image preview to freeze/unfreeze +!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram +!HISTOGRAM_TOOLTIP_FULL;Toggle full (on) or scaled (off) 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;Lab - Chromaticity +!HISTORY_MSG_96;'a' Curve +!HISTORY_MSG_97;'b' Curve +!HISTORY_MSG_98;Demosaicing Method +!HISTORY_MSG_99;Hot/Dead pixel filter +!HISTORY_MSG_100;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;Resizing applies to +!HISTORY_MSG_111;Lab - Avoid color shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;Lab - Protection +!HISTORY_MSG_114;DCB Iterations +!HISTORY_MSG_115;False Color Suppression +!HISTORY_MSG_116;DCB Enhancement +!HISTORY_MSG_117;Raw Red CA Correction +!HISTORY_MSG_118;Raw Blue CA Correction +!HISTORY_MSG_119;Line Noise Filter +!HISTORY_MSG_120;Green Equilibration +!HISTORY_MSG_121;Raw Auto CA +!HISTORY_MSG_122;Dark Frame Auto Select +!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 Select +!HISTORY_MSG_128;Flat Field Blur Radius +!HISTORY_MSG_129;Flat Field Blur Type +!HISTORY_MSG_130;Auto Distorion +!HISTORY_MSG_131;Noise Reduction Luma +!HISTORY_MSG_132;Noise Reduction 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;Edges Sharpening +!HISTORY_MSG_147;ES - Luminance Only +!HISTORY_MSG_148;Microcontrast +!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_150;Post Demosaic Artifact/Noise Reduction +!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;'CC' curve +!HISTORY_MSG_169;'CH' curve +!HISTORY_MSG_170;Vib - Curve +!HISTORY_MSG_171;'LC' curve +!HISTORY_MSG_172;Lab - 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 tones protection +!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 pixels +!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;'CL' curve +!HISTORY_MSG_247;'LH' curve +!HISTORY_MSG_248;'HH' curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +!MAIN_BUTTON_FULLSCREEN;Fullscreen +!MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the Next image relative to image open in Editor\nShortcut: Shift-F4\n\nTo navigate to the Next image relative to thumbnail selected in File Browser\nShortcut: F4 +!MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the Previous image relative to image open in Editor\nShortcut: Shift-F3 \n\nTo navigate to the Previous image relative to thumbnail selected in File Browser\nShortcut: F3 +!MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronize the File Browser with the Editor to reveal the thumbnail of the currently open image, and clear filters in File Browser \nShortcut: x\n\nAs above, but without clearing filters in File Browser\nShortcut: y\n(Note that thumbnail of the open file 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\ndoesn't exist. Please set a correct path in the Preference window. +!MAIN_MSG_SETPATHFIRST;You have to set a target path first in Preferences\nin order to use this function! +!MAIN_MSG_WRITEFAILED;Failed to write\n\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_METADATA_TOOLTIP;Shortcut: Alt-m +!MAIN_TAB_RAW;Raw +!MAIN_TAB_RAW_TOOLTIP;Shortcut: Alt-r +!MAIN_TAB_TRANSFORM_TOOLTIP;Shortcut: Alt-t +!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 10-30%\n\nPreview is rendered slower with Focus Mask turned on. +!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_NA;B = n/a +!NAVIGATOR_B_VALUE;B = %1 +!NAVIGATOR_G_NA;G = n/a +!NAVIGATOR_G_VALUE;G = %1 +!NAVIGATOR_H_NA;H = n/a +!NAVIGATOR_H_VALUE;H = %1 +!NAVIGATOR_LAB_A_NA;a = n/a +!NAVIGATOR_LAB_A_VALUE;a = %1 +!NAVIGATOR_LAB_B_NA;b = n/a +!NAVIGATOR_LAB_B_VALUE;b = %1 +!NAVIGATOR_LAB_L_NA;L = n/a +!NAVIGATOR_LAB_L_VALUE;L = %1 +!NAVIGATOR_R_NA;R = n/a +!NAVIGATOR_R_VALUE;R = %1 +!NAVIGATOR_S_NA;S = n/a +!NAVIGATOR_S_VALUE;S = %1 +!NAVIGATOR_V_NA;V = n/a +!NAVIGATOR_V_VALUE;V = %1 +!NAVIGATOR_XY_FULL;Width = %1, Height = %2 +!NAVIGATOR_XY_NA;x = n/a, y = n/a +!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;CIE Color Appearance Model 2002 +!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_EVERYTHING;Everything +!PARTIALPASTE_FLATFIELDAUTOSELECT;Flat field auto selection +!PARTIALPASTE_FLATFIELDBLURRADIUS;Flat field blur radius +!PARTIALPASTE_FLATFIELDBLURTYPE;Flat field blur type +!PARTIALPASTE_FLATFIELDFILE;Flat field file +!PARTIALPASTE_GRADIENT;Graduated filter +!PARTIALPASTE_HSVEQUALIZER;HSV equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!PARTIALPASTE_LABCURVE;Lab adjustments +!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_PERSPECTIVE;Perspective +!PARTIALPASTE_PREPROCESS_GREENEQUIL;Green equilibration +!PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Apply hot/dead 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_ALLENHANCE;Post-demosaic artifact/noise reduction +!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 +!PREFERENCES_ADD;Add +!PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!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_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_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 scipts 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_DATEFORMATFRAME;Date Format +!PREFERENCES_DIRDARKFRAMES;Dark frames directory +!PREFERENCES_EDITORLAYOUT;Editor Layout +!PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar (de-select for low resolution display) +!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_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;Output device's Yb luminance (%) +!PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogram in left panel +!PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Show embedded JPEG thumbnail if raw is unedited +!PREFERENCES_LANGAUTODETECT;Use OS language setting +!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_MULTITABDUALMON;Multiple Editor Tabs Mode (if available on second monitor) +!PREFERENCES_MULTITAB;Multiple Editor Tabs Mode +!PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails +!PREFERENCES_OVERWRITEOUTPUTFILE;Overwrite existing output files +!PREFERENCES_PANFACTORFRAME;Pan Rate Amplification +!PREFERENCES_PANFACTORLABEL;Factor +!PREFERENCES_PROPERTY;Property +!PREFERENCES_RGBDTL_LABEL;Max number of threads for Noise Reduction +!PREFERENCES_RGBDTL_TOOLTIP;Noise Reduction requires a baseline of about 128MB RAM for a 10MPix image or 512MB for a 40MPix image, and additionally 128MB RAM per thread. The more threads run in parallel, the faster the computation. Leave the setting at "0" to automatically use as many threads as possible. +!PREFERENCES_SELECTFONT;Select font +!PREFERENCES_SET;Set +!PREFERENCES_SHOWEXPOSURECOMPENSATION;Append exposure compensation +!PREFERENCES_SHOWPROFILESELECTOR;Show processing profile selector +!PREFERENCES_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs +!PREFERENCES_SINGLETAB;Single Editor Tab Mode +!PREFERENCES_SLIMUI;Slim interface +!PREFERENCES_SND_BATCHQUEUEDONE;Queue processing done +!PREFERENCES_SND_HELP;Either enter filepath or nothing (for no sound).\nOn Windows use "SystemDefault", "SystemAsterisk" etc. for system sounds.\nOn Linux use "complete", "window-attention" etc. for system sounds. +!PREFERENCES_SND_LNGEDITPROCDONE;Editor processing done +!PREFERENCES_SND_TRESHOLDSECS;after secs +!PREFERENCES_SQUAREDETAILWINDOW;Square detail window (faster) +!PREFERENCES_TAB_PERFORMANCE;Performance +!PREFERENCES_TAB_SOUND;Sounds +!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_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_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing channel-mixer +!TP_BWMIX_BLUE;Blue +!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;Modify luminance in function of hue\nPay attention to extreme values that may cause artifacts +!TP_BWMIX_CYAN;Cyan +!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 simulate shots taken with a colored filter placed in front of the lens. Colored filters reduce transmission of specific range of colors and correspondingly affect their lightness. E.g. a Red filter darkens Blue skies. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_BLUE;Blue Channel +!TP_BWMIX_GAM_GREEN;Green Channel +!TP_BWMIX_GAM_RED;Red Channel +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each channel RGB +!TP_BWMIX_GREEN;Green +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MAGENTA;Magenta +!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 (filter, channel-mixer) to default +!TP_BWMIX_ORANGE;Orange +!TP_BWMIX_PURPLE;Purple +!TP_BWMIX_RED;Red +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all of the mixer options\nTotal displays the sum of RGB values actually applied:\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 (films, landscape, ...) or manual settings of channel-mixer +!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;Channel-Mixer absolute RGB +!TP_BWMIX_SET_RGBREL;Channel-Mixer relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Channel-Mixer absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Channel-Mixer 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_BWMIX_YELLOW;Yellow +!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) RT 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.\n 0=no effect 1=median 2=gaussian.\n\nThese artifacts are due to limitations of CIECAM02. Alternatively, adjust the image to avoid very dark shadows. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from Lab and RGB brightness +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from Lab and RGB colorfulness +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from Lab and RGB saturation +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from Lab 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 Lab and RGB contrast +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from Lab and RGB contrast +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L (Lab) 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 (Lab) 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 Lab values before CIECAM02 adjustments +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RT 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 (Lab) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in Lab 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 Lab and RGB lightness +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model\n\nWB [RT] + [output]:\nRT's white balance is used for the scene, CIECAM02 is set to D50, the output device's white balance is set in Preferences > Color Management\n\nWB [RT+CAT02] + [output]:\nRT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences +!TP_COLORAPP_RSTPRO;Red & skin tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin tones protection (sliders and curves) +!TP_COLORAPP_SHARPCIE;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe with Q/C +!TP_COLORAPP_SHARPCIE_TOOLTIP;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe will use CIECAM02 if enabled. +!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;Change tones and colors to take into account the viewing conditions of the output device\n\nAverage:\nAverage light environment (standard)\nThe image will not change\n\nDim:\nDim environment (TV)\nThe image will become slighty dark\n\nDark:\nDark environment (projector)\nThe image will become more dark\n\nExtremly Dark:\nExtremly dark environment (cutsheet)\nThe image will become very dark +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if source 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 Lab 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_CROP_GTEPASSPORT;Biometric Passport +!TP_CROP_GTFRAME;Frame +!TP_CROP_GTGRID;Grid +!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_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_CHROMA;Chrominance - Master +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on gamma of the input color profile. Gamma of sRGB is assumed, thus if input image is in color profile of a different gamma, luminance noise reduction will vary. +!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_LAB;Lab +!TP_DIRPYRDENOISE_LDETAIL;Luminance Detail +!TP_DIRPYRDENOISE_LUMA;Luminance +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or Lab methods can be used.\n\nFor non-raw images Lab method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_PERF;RGB mode (raw images) +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGB;RGB +!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_THRESHOLD;Threshold +!TP_DISTORTION_AUTO;Auto Distortion Correction +!TP_DISTORTION_AUTO_TIP;(Exprimental) Correct lens distortion automatically for some cameras (Micro 4/3, some compact digital cameras, etc.) +!TP_EPD_EDGESTOPPING;Edge Stopping +!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 via Lab mode (standard) and CIECAM02 mode.\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_EXPOSCORR_LABEL;Raw White & Black Points +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggle execution of auto levels to automatically set parameter values based on image analysis\nEnable Highlight Reconstruction if necessary +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in auto level's 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 following section of the manual to learn how to achieve the best results with double curves:\nThe Toolbox > Exposure Tab > Exposure Panel > Tone Curve +!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_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!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_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 effect of this tool or some of its sub-component is only visible at 1:1 preview scale. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Rotation anchor point X: -100=left edge, 0=center, +100=right edge +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Rotation anchor point Y: -100=top edge, 0=center, +100=bottom edge +!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 automatic exposure +!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 blown 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 simple color matrix by dcraw, enhanced RawTherapee version (whichever is available based on camera model) or embedded in 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. Use only in special cases. +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. Result can be used for calibration purposes, 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;Lab 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;Can be used with the Chromaticity slider and the CC curve. +!TP_LENSGEOM_AUTOCROP;Auto Crop +!TP_LENSGEOM_FILL;Auto fill +!TP_LENSGEOM_LABEL;Lens / Geometry +!TP_LENSPROFILE_FILEDLGFILTERLCP;Lens correction files +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;CA Correction +!TP_LENSPROFILE_USEDIST;Distortion correction +!TP_LENSPROFILE_USEVIGN;Vignetting correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset 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: 0=corners only, 50=halfway to center, 100=to center +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness: 0=rectangle, 50=fitted ellipse, 100=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. Higher = more, lower = less. +!TP_PREPROCESS_GREENEQUIL;Green Equilibration +!TP_PREPROCESS_HOTDEADPIXFILT;Hot/Dead pixel filter +!TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Try to suppress hot and dead 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_BLACKONE;Black Level: Red +!TP_RAWEXPOS_BLACKS;Black Levels +!TP_RAWEXPOS_BLACKTHREE;Black Level: Green 2 +!TP_RAWEXPOS_BLACKTWO;Black Level: Blue +!TP_RAWEXPOS_BLACKZERO;Black Level: Green 1 (lead) +!TP_RAWEXPOS_LINEAR;White Point Correction +!TP_RAWEXPOS_PRESER;Highlight Preservation +!TP_RAWEXPOS_TWOGREEN;Link greens +!TP_RAW_ALLENHANCE;Post-Demosaic Artifact/Noise Reduction +!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 +!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_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 used 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_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_ZOOMFITSCREEN;Fit 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..fa1932b99 --- /dev/null +++ b/rtdata/languages/Francais @@ -0,0 +1,1395 @@ +#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_CURVES;Courbes +CURVEEDITOR_CURVE;Courbe +CURVEEDITOR_CUSTOM;Personnalisé +CURVEEDITOR_DARKS;Zones sombres +CURVEEDITOR_FILEDLGFILTERANY;Tous les fichiers +CURVEEDITOR_FILEDLGFILTERCURVE;Fichiers de courbe +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: +EDITWINDOW_TITLE;Édition d'image +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_COLORDENOISE;Ignorer la réduction du bruit chromatique +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_LUMADENOISE;Ignorer la réduction du bruit de luminance +EXPORT_BYPASS_RAW_ALL_ENHANCE;Ignorer la réduction de bruit/artefact post-dématriçage +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 +EXPORT_RESIZEMETHOD;Méthode de redimensionnement +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_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_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_POPUPRANK;Étoiles +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: 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_USETEMPLATE;Utiliser le modèle: +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_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_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_TAGGING;Étiquetter +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_B_NA;B = n/d +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_G_NA;V = n/d +NAVIGATOR_G_VALUE;V = %1 +NAVIGATOR_H_NA;T = n/d +NAVIGATOR_H_VALUE;T = %1 +NAVIGATOR_LAB_A_NA;a = n/d +NAVIGATOR_LAB_A_VALUE;a = %1 +NAVIGATOR_LAB_B_NA;b = n/d +NAVIGATOR_LAB_B_VALUE;b = %1 +NAVIGATOR_LAB_L_NA;L = n/d +NAVIGATOR_LAB_L_VALUE;L = %1 +NAVIGATOR_R_NA;R = n/d +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_S_NA;S = n/d +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_NA;V = n/d +NAVIGATOR_V_VALUE;V = %1 +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_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_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_METAICMGROUP;Réglages des Métadonnées/ICM +PARTIALPASTE_PCVIGNETTE;Filtre Vignettage +PARTIALPASTE_PERSPECTIVE;Perspective +PARTIALPASTE_PREPROCESS_GREENEQUIL;Équilibrage du vert +PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Filtrage des pixels chauds/morts +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_ALLENHANCE;Réduction de bruit/artefact post-dématriçage +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_BLINKCLIPPED;Faire clignoter les zones hors domaine +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_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_DATEFORMATFRAME;Format de la date +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_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_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_GTKTHEME;GTK par défaut +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_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 +PREFERENCES_OVERWRITEOUTPUTFILE;Écraser le fichier s'il existe déjà +PREFERENCES_PANFACTORFRAME;Amplification du déplacement +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_SHOWPROFILESELECTOR;Affiche le sélecteur de profils +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_SQUAREDETAILWINDOW;Fenêtre de détail carrée (plus rapide) +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_FILEDLGFILTERANY;Tous les fichiers +PROFILEPANEL_FILEDLGFILTERPP;Profils de post-traitement +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_JPGFILTER;Fichiers 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_TIFFFILTER;Fichiers TIFF +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_BLUE;Bleu +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_CYAN;Cyan +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_BLUE;Canal Bleu +TP_BWMIX_GAM_GREEN;Canal Vert +TP_BWMIX_GAM_RED;Canal Rouge +TP_BWMIX_GAM_TOOLTIP;Corrige le gamma pour chaque canaux RVB +TP_BWMIX_GREEN;Vert +TP_BWMIX_LABEL;Noir & Blanc +TP_BWMIX_MAGENTA;Magenta +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_ORANGE;Orange +TP_BWMIX_PURPLE;Pourpre +TP_BWMIX_RED;Rouge +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;Mixeur de Canaux - RVB Absolu +TP_BWMIX_SET_RGBREL;Mixeur de Canaux - RVB Relatif +TP_BWMIX_SET_ROYGCBPMABS;Mixeur de Canaux - ROJVCBPM Absolu +TP_BWMIX_SET_ROYGCBPMREL;Mixeur de Canaux - 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_BWMIX_YELLOW;Jaune +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_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_GTHARMMEANS1;Manière harmonique 1 +TP_CROP_GTHARMMEANS2;Manière harmonique 2 +TP_CROP_GTHARMMEANS3;Manière harmonique 3 +TP_CROP_GTHARMMEANS4;Manière harmonique 4 +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_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_LUMA;Luminance +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_PERF;Mode RVB (images raw) +TP_DIRPYRDENOISE_RED;Chrominance - Rouge-Vert +TP_DIRPYRDENOISE_RGB;RVB +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_THRESHOLD;Seuil +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_EXPOSCORR_LABEL;Points Noir & Blanc Raw +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_SATANDVALBLENDING;Mixage Saturation et Valeur +TP_EXPOSURE_TCMODE_STANDARD;Standard +TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Standard Pondéré +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_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;L'effet de cet outil ou de l'un de ses sous-composant n'est visible 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_FILEDLGFILTERANY;Tous les fichiers +TP_ICM_FILEDLGFILTERICM;Fichiers de profil +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_FILEDLGFILTERLCP;Fichiers de correction d'objectif +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_GREENEQUIL;Équilibrage du vert +TP_PREPROCESS_HOTDEADPIXFILT;Filtrer les pixels chauds/morts +TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Essaie de supprimer les pixels chauds/morts +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_BLACKONE;Niveau de noir: Rouge +TP_RAWEXPOS_BLACKS;Niveaux de noir +TP_RAWEXPOS_BLACKTHREE;Niveau de noir: Vert 2 +TP_RAWEXPOS_BLACKTWO;Niveau de noir: Bleu +TP_RAWEXPOS_BLACKZERO;Niveau de noir: Vert 1 (maître) +TP_RAWEXPOS_LINEAR;Corr. du Point Blanc +TP_RAWEXPOS_PRESER;Préservation des HL +TP_RAWEXPOS_TWOGREEN;Lier les verts +TP_RAW_ALLENHANCE;Réduction de bruit/artefact post-dématriçage +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_RESIZE_APPLIESTO;S'applique à: +TP_RESIZE_BICUBICSF;Bicubique (Plus doux) +TP_RESIZE_BICUBICSH;Bicubique (Plus net) +TP_RESIZE_BICUBIC;Bicubique +TP_RESIZE_BILINEAR;Bilinéaire +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: - + diff --git a/rtdata/languages/Greek b/rtdata/languages/Greek new file mode 100644 index 000000000..b929811af --- /dev/null +++ b/rtdata/languages/Greek @@ -0,0 +1,1440 @@ +#01 2008-05-14 zeusalmighty + +ADJUSTER_RESET_TO_DEFAULT;Επαναφορά προεπιλογών +CURVEEDITOR_FILEDLGFILTERANY;Οποιοδήποτε αρχείο +CURVEEDITOR_FILEDLGFILTERCURVE;Αρχεία καμπυλών +CURVEEDITOR_LINEAR;Γραμμικό +CURVEEDITOR_LOADDLGLABEL;Φόρτωση καμπύλης... +CURVEEDITOR_SAVEDLGLABEL;Αποθήκευση καμπλης... +CURVEEDITOR_TOOLTIPLINEAR;Επαναφορά καμπύλης σε γραμμική +CURVEEDITOR_TOOLTIPLOAD;Φόρτωση καμπύλης απο αρχείο +CURVEEDITOR_TOOLTIPSAVE;Αποθήκευση παρούσας καμπύλης +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_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_SAVEAS;Ως... +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_TAGGING;Tagging +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_LUMACURVE;Luminance curve +PARTIALPASTE_METAICMGROUP;Metadata/ICM settings +PARTIALPASTE_RESIZE;Resize +PARTIALPASTE_ROTATION;Rotation +PARTIALPASTE_SHADOWSHIGHLIGHTS;Shadows/Highlights +PARTIALPASTE_SHARPENING;Sharpening +PARTIALPASTE_VIGNETTING;Vignetting correction +PARTIALPASTE_WHITEBALANCE;White balance +PREFERENCES_APPLNEXTSTARTUP;εφαρμόζεται στην επόμενη εκκίνηση +PREFERENCES_BLINKCLIPPED;Οι περιοχές ψαλιδίσματος να αναβοσβήνουν +PREFERENCES_CACHECLEARALL;Clear All +PREFERENCES_CACHECLEARPROFILES;Clear Profiles +PREFERENCES_CACHECLEARTHUMBS;Clear Thumbnails +PREFERENCES_CACHEFORMAT1;Proprietary (faster and better quality) +PREFERENCES_CACHEFORMAT2;JPEG (smaller disk footprint) +PREFERENCES_CACHEMAXENTRIES;Maximal Number of Cache Entries +PREFERENCES_CACHEOPTS;Cache Options +PREFERENCES_CACHETHUMBFORM;Cache Thumbnail Format +PREFERENCES_CACHETHUMBHEIGHT;Maximal Thumbnail Height +PREFERENCES_CLEARDLG_LINE1;Clearing cache +PREFERENCES_CLEARDLG_LINE2;This may take a few seconds. +PREFERENCES_CLEARDLG_TITLE;Please wait +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_GTKTHEME;Προεπιλεγμένη GTK +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_FILEDLGFILTERANY;Οποιοφήποτε αρχείο +PROFILEPANEL_FILEDLGFILTERPP;Προφίλ επεξεργασίας +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... +PROGRESSDLG_LOADING;Loading file... +PROGRESSDLG_PROCESSING;Processing image... +PROGRESSDLG_SAVING;Saving file... +QINFO_ISO;ISO +QINFO_NOEXIF;Στοιχεία Exif μη διαθέσιμα. +SAVEDLG_FILEFORMAT;Είδος αρχείου +SAVEDLG_JPEGQUAL;Ποιότητα JPEG +SAVEDLG_JPGFILTER;Αρχεία 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;Αποθήκευση παραμέτρων επεξεργασίας μαζί με την εικόνα +SAVEDLG_TIFFFILTER;Αρχεία TIFF +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_DEGREE;γωνία: +TP_COARSETRAF_TOOLTIP_HFLIP;Αναστροφή οριζόντια +TP_COARSETRAF_TOOLTIP_ROTLEFT;Περιστροφή αριστερά +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Περιστροφή δεξιά +TP_COARSETRAF_TOOLTIP_VFLIP;Αναστροφή κατακόρυφα +TP_COLORBOOST_ACHANNEL;κανάλι "a" +TP_COLORBOOST_AMOUNT;Ένταση +TP_COLORBOOST_AVOIDCOLORCLIP;Αποφυγή ψαλιδίσματος χρώματος +TP_COLORBOOST_BCHANNEL;κανάλι "b" +TP_COLORBOOST_CHANNEL;Κανάλι +TP_COLORBOOST_CHSEPARATE;ξεχωριστά +TP_COLORBOOST_ENABLESATLIMITER;Ενεργοποίηση περιορισμού κορεσμού +TP_COLORBOOST_LABEL;Ενίσχυση χρώματος +TP_COLORBOOST_SATLIMIT;Περιορισμός κορεσμού +TP_COLORDENOISE_EDGESENSITIVE;Ευαισθησία ορίων +TP_COLORDENOISE_EDGETOLERANCE;Ανοχή ορίων +TP_COLORDENOISE_LABEL;Μείωση χρωματικού θορύβου +TP_COLORDENOISE_RADIUS;Ακτίνα +TP_COLORSHIFT_BLUEYELLOW;Μπλέ-Κίτρινο +TP_COLORSHIFT_GREENMAGENTA;Πράσινο-Magenta +TP_COLORSHIFT_LABEL;Μετατόπιση χρώματος +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;Κλείδωμα αναλογίας: +TP_CROP_GTDIAGONALS;Κανόνας διαγωνίων +TP_CROP_GTHARMMEANS1;Harmonic means 1 +TP_CROP_GTHARMMEANS2;Harmonic means 2 +TP_CROP_GTHARMMEANS3;Harmonic means 3 +TP_CROP_GTHARMMEANS4;Harmonic means 4 +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_FILEDLGFILTERANY;Οποιοδήποτε αρχείο +TP_ICM_FILEDLGFILTERICM;Αρχεία προφίλ ICC +TP_ICM_GAMMABEFOREINPUT;Το προφίλ αλλάζει την gamma +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_LUMACURVE_BLACKLEVEL;Μαύρα +TP_LUMACURVE_BRIGHTNESS;Φωτεινότητα +TP_LUMACURVE_COMPRHIGHLIGHTS;Συμπίεση φωτεινών σημείων +TP_LUMACURVE_COMPRSHADOWS;Συμπίεση σκιών +TP_LUMACURVE_CONTRAST;Αντίθεση +TP_LUMACURVE_CURVEEDITOR;Καμπύλη φωτεινότητας +TP_LUMACURVE_LABEL;Καμπύλη φωτεινότητας +TP_RAW_DMETHOD;Μέθοδος +TP_RAW_FALSECOLOR;Βήματα καταστολής σφαλμένων χρωμάτων +TP_RESIZE_BICUBICSF;Bicubic (Softer) +TP_RESIZE_BICUBICSH;Bicubic (Sharper) +TP_RESIZE_BICUBIC;Bicubic +TP_RESIZE_BILINEAR;Bilinear +TP_RESIZE_H;H: +TP_RESIZE_LABEL;Αλλαγή μεγέθους +TP_RESIZE_METHOD;Μέθοδος: +TP_RESIZE_NEAREST;Nearest +TP_RESIZE_SCALE;Κλίμακα +TP_RESIZE_W;W: +TP_ROTATE_AUTOCROP;Αυτόματη αποκοπή +TP_ROTATE_DEGREE;Γωνία +TP_ROTATE_FILL;Γέμισμα εικόνας +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_CURVES;Curves +!CURVEEDITOR_CURVE;Curve +!CURVEEDITOR_CUSTOM;Custom +!CURVEEDITOR_DARKS;Darks +!CURVEEDITOR_HIGHLIGHTS;Highlights +!CURVEEDITOR_LIGHTS;Lights +!CURVEEDITOR_MINMAXCPOINTS;Minima/Maxima control points +!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 +!EXIFFILTER_EXPOSURECOMPENSATION;Exposure Compensation (EV) +!EXIFFILTER_FILETYPE;File Type +!EXIFFILTER_METADATAFILTER;Enable Metadata Filters +!EXPORT_BYPASS_ALL;Select / Unselect All +!EXPORT_BYPASS_COLORDENOISE;Bypass Color denoise +!EXPORT_BYPASS_DEFRINGE;Bypass Defringe +!EXPORT_BYPASS_DIRPYRDENOISE;Bypass Noise Reduction +!EXPORT_BYPASS_DIRPYREQUALIZER;Bypass Contrast by Detail Levels +!EXPORT_BYPASS_LUMADENOISE;Bypass Luma denoise +!EXPORT_BYPASS_RAW_ALL_ENHANCE;Bypass Post Demosaic Artifact/Noise Reduction +!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 +!EXPORT_RESIZEMETHOD;Resize 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.\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\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_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_POPUPRANK;Rank +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!FILEBROWSER_QUERYHINT;Type a partial filename to search for or a comma-separated list.\nE.g. 1001,1004,1199 \n\nCtrl-F to focus to the Find text box.\nEnter to commence search.\nEsc to clear.\nShift-Esc to remove focus. +!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.\nShortcut: i\n\nShortcut in Single Editor Tab Mode: Alt-i +!FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show images recently saved.\nShortcut: Alt-7 +!FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show images not recently saved.\nShortcut: Alt-6 +!FILEBROWSER_SHOWUNCOLORHINT;Show images without Color label.\nShortcut: Alt-0 +!FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +!FILEBROWSER_UNRANK_TOOLTIP;Unrank\nShortcut: Shift-0 +!FILEBROWSER_USETEMPLATE;Use template: +!GENERAL_AFTER;After +!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\nClick right mouse button on image preview to freeze/unfreeze +!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram +!HISTOGRAM_TOOLTIP_FULL;Toggle full (on) or scaled (off) 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;Lab - Chromaticity +!HISTORY_MSG_96;'a' Curve +!HISTORY_MSG_97;'b' Curve +!HISTORY_MSG_98;Demosaicing Method +!HISTORY_MSG_99;Hot/Dead pixel filter +!HISTORY_MSG_100;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;Resizing applies to +!HISTORY_MSG_111;Lab - Avoid color shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;Lab - Protection +!HISTORY_MSG_114;DCB Iterations +!HISTORY_MSG_115;False Color Suppression +!HISTORY_MSG_116;DCB Enhancement +!HISTORY_MSG_117;Raw Red CA Correction +!HISTORY_MSG_118;Raw Blue CA Correction +!HISTORY_MSG_119;Line Noise Filter +!HISTORY_MSG_120;Green Equilibration +!HISTORY_MSG_121;Raw Auto CA +!HISTORY_MSG_122;Dark Frame Auto Select +!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 Select +!HISTORY_MSG_128;Flat Field Blur Radius +!HISTORY_MSG_129;Flat Field Blur Type +!HISTORY_MSG_130;Auto Distorion +!HISTORY_MSG_131;Noise Reduction Luma +!HISTORY_MSG_132;Noise Reduction 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;Edges Sharpening +!HISTORY_MSG_147;ES - Luminance Only +!HISTORY_MSG_148;Microcontrast +!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_150;Post Demosaic Artifact/Noise Reduction +!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;'CC' curve +!HISTORY_MSG_169;'CH' curve +!HISTORY_MSG_170;Vib - Curve +!HISTORY_MSG_171;'LC' curve +!HISTORY_MSG_172;Lab - 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 tones protection +!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 pixels +!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;'CL' curve +!HISTORY_MSG_247;'LH' curve +!HISTORY_MSG_248;'HH' curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +!MAIN_BUTTON_FULLSCREEN;Fullscreen +!MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the Next image relative to image open in Editor\nShortcut: Shift-F4\n\nTo navigate to the Next image relative to thumbnail selected in File Browser\nShortcut: F4 +!MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the Previous image relative to image open in Editor\nShortcut: Shift-F3 \n\nTo navigate to the Previous image relative to thumbnail selected in File Browser\nShortcut: F3 +!MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronize the File Browser with the Editor to reveal the thumbnail of the currently open image, and clear filters in File Browser \nShortcut: x\n\nAs above, but without clearing filters in File Browser\nShortcut: y\n(Note that thumbnail of the open file 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\ndoesn't exist. Please set a correct path in the Preference window. +!MAIN_MSG_SETPATHFIRST;You have to set a target path first in Preferences\nin order to use this function! +!MAIN_MSG_WRITEFAILED;Failed to write\n\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_METADATA_TOOLTIP;Shortcut: Alt-m +!MAIN_TAB_RAW;Raw +!MAIN_TAB_RAW_TOOLTIP;Shortcut: Alt-r +!MAIN_TAB_TRANSFORM_TOOLTIP;Shortcut: Alt-t +!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 10-30%\n\nPreview is rendered slower with Focus Mask turned on. +!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_NA;B = n/a +!NAVIGATOR_B_VALUE;B = %1 +!NAVIGATOR_G_NA;G = n/a +!NAVIGATOR_G_VALUE;G = %1 +!NAVIGATOR_H_NA;H = n/a +!NAVIGATOR_H_VALUE;H = %1 +!NAVIGATOR_LAB_A_NA;a = n/a +!NAVIGATOR_LAB_A_VALUE;a = %1 +!NAVIGATOR_LAB_B_NA;b = n/a +!NAVIGATOR_LAB_B_VALUE;b = %1 +!NAVIGATOR_LAB_L_NA;L = n/a +!NAVIGATOR_LAB_L_VALUE;L = %1 +!NAVIGATOR_R_NA;R = n/a +!NAVIGATOR_R_VALUE;R = %1 +!NAVIGATOR_S_NA;S = n/a +!NAVIGATOR_S_VALUE;S = %1 +!NAVIGATOR_V_NA;V = n/a +!NAVIGATOR_V_VALUE;V = %1 +!NAVIGATOR_XY_FULL;Width = %1, Height = %2 +!NAVIGATOR_XY_NA;x = n/a, y = n/a +!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;CIE Color Appearance Model 2002 +!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_EVERYTHING;Everything +!PARTIALPASTE_FLATFIELDAUTOSELECT;Flat field auto selection +!PARTIALPASTE_FLATFIELDBLURRADIUS;Flat field blur radius +!PARTIALPASTE_FLATFIELDBLURTYPE;Flat field blur type +!PARTIALPASTE_FLATFIELDFILE;Flat field file +!PARTIALPASTE_GRADIENT;Graduated filter +!PARTIALPASTE_HSVEQUALIZER;HSV equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!PARTIALPASTE_LABCURVE;Lab adjustments +!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_PERSPECTIVE;Perspective +!PARTIALPASTE_PREPROCESS_GREENEQUIL;Green equilibration +!PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Apply hot/dead 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_ALLENHANCE;Post-demosaic artifact/noise reduction +!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 +!PREFERENCES_ADD;Add +!PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!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_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_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 scipts 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_DATEFORMATFRAME;Date Format +!PREFERENCES_DIRDARKFRAMES;Dark frames directory +!PREFERENCES_EDITORLAYOUT;Editor Layout +!PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar (de-select for low resolution display) +!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_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;Output device's Yb luminance (%) +!PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogram in left panel +!PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Show embedded JPEG thumbnail if raw is unedited +!PREFERENCES_LANGAUTODETECT;Use OS language setting +!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_MULTITABDUALMON;Multiple Editor Tabs Mode (if available on second monitor) +!PREFERENCES_MULTITAB;Multiple Editor Tabs Mode +!PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails +!PREFERENCES_OVERWRITEOUTPUTFILE;Overwrite existing output files +!PREFERENCES_PANFACTORFRAME;Pan Rate Amplification +!PREFERENCES_PANFACTORLABEL;Factor +!PREFERENCES_PROPERTY;Property +!PREFERENCES_RGBDTL_LABEL;Max number of threads for Noise Reduction +!PREFERENCES_RGBDTL_TOOLTIP;Noise Reduction requires a baseline of about 128MB RAM for a 10MPix image or 512MB for a 40MPix image, and additionally 128MB RAM per thread. The more threads run in parallel, the faster the computation. Leave the setting at "0" to automatically use as many threads as possible. +!PREFERENCES_SELECTFONT;Select font +!PREFERENCES_SET;Set +!PREFERENCES_SHOWEXPOSURECOMPENSATION;Append exposure compensation +!PREFERENCES_SHOWPROFILESELECTOR;Show processing profile selector +!PREFERENCES_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs +!PREFERENCES_SINGLETAB;Single Editor Tab Mode +!PREFERENCES_SLIMUI;Slim interface +!PREFERENCES_SND_BATCHQUEUEDONE;Queue processing done +!PREFERENCES_SND_HELP;Either enter filepath or nothing (for no sound).\nOn Windows use "SystemDefault", "SystemAsterisk" etc. for system sounds.\nOn Linux use "complete", "window-attention" etc. for system sounds. +!PREFERENCES_SND_LNGEDITPROCDONE;Editor processing done +!PREFERENCES_SND_TRESHOLDSECS;after secs +!PREFERENCES_SQUAREDETAILWINDOW;Square detail window (faster) +!PREFERENCES_TAB_PERFORMANCE;Performance +!PREFERENCES_TAB_SOUND;Sounds +!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_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_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing channel-mixer +!TP_BWMIX_BLUE;Blue +!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;Modify luminance in function of hue\nPay attention to extreme values that may cause artifacts +!TP_BWMIX_CYAN;Cyan +!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 simulate shots taken with a colored filter placed in front of the lens. Colored filters reduce transmission of specific range of colors and correspondingly affect their lightness. E.g. a Red filter darkens Blue skies. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_BLUE;Blue Channel +!TP_BWMIX_GAM_GREEN;Green Channel +!TP_BWMIX_GAM_RED;Red Channel +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each channel RGB +!TP_BWMIX_GREEN;Green +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MAGENTA;Magenta +!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 (filter, channel-mixer) to default +!TP_BWMIX_ORANGE;Orange +!TP_BWMIX_PURPLE;Purple +!TP_BWMIX_RED;Red +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all of the mixer options\nTotal displays the sum of RGB values actually applied:\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 (films, landscape, ...) or manual settings of channel-mixer +!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;Channel-Mixer absolute RGB +!TP_BWMIX_SET_RGBREL;Channel-Mixer relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Channel-Mixer absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Channel-Mixer 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_BWMIX_YELLOW;Yellow +!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) RT 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.\n 0=no effect 1=median 2=gaussian.\n\nThese artifacts are due to limitations of CIECAM02. Alternatively, adjust the image to avoid very dark shadows. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from Lab and RGB brightness +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from Lab and RGB colorfulness +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from Lab and RGB saturation +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from Lab 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 Lab and RGB contrast +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from Lab and RGB contrast +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L (Lab) 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 (Lab) 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 Lab values before CIECAM02 adjustments +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RT 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 (Lab) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in Lab 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 Lab and RGB lightness +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model\n\nWB [RT] + [output]:\nRT's white balance is used for the scene, CIECAM02 is set to D50, the output device's white balance is set in Preferences > Color Management\n\nWB [RT+CAT02] + [output]:\nRT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences +!TP_COLORAPP_RSTPRO;Red & skin tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin tones protection (sliders and curves) +!TP_COLORAPP_SHARPCIE;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe with Q/C +!TP_COLORAPP_SHARPCIE_TOOLTIP;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe will use CIECAM02 if enabled. +!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;Change tones and colors to take into account the viewing conditions of the output device\n\nAverage:\nAverage light environment (standard)\nThe image will not change\n\nDim:\nDim environment (TV)\nThe image will become slighty dark\n\nDark:\nDark environment (projector)\nThe image will become more dark\n\nExtremly Dark:\nExtremly dark environment (cutsheet)\nThe image will become very dark +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if source 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 Lab 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_CROP_GTEPASSPORT;Biometric Passport +!TP_CROP_GTFRAME;Frame +!TP_CROP_GTGRID;Grid +!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_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_CHROMA;Chrominance - Master +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on gamma of the input color profile. Gamma of sRGB is assumed, thus if input image is in color profile of a different gamma, luminance noise reduction will vary. +!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_LAB;Lab +!TP_DIRPYRDENOISE_LDETAIL;Luminance Detail +!TP_DIRPYRDENOISE_LUMA;Luminance +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or Lab methods can be used.\n\nFor non-raw images Lab method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_PERF;RGB mode (raw images) +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGB;RGB +!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_THRESHOLD;Threshold +!TP_DISTORTION_AUTO;Auto Distortion Correction +!TP_DISTORTION_AUTO_TIP;(Exprimental) Correct lens distortion automatically for some cameras (Micro 4/3, some compact digital cameras, etc.) +!TP_EPD_EDGESTOPPING;Edge Stopping +!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 via Lab mode (standard) and CIECAM02 mode.\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_EXPOSCORR_LABEL;Raw White & Black Points +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggle execution of auto levels to automatically set parameter values based on image analysis\nEnable Highlight Reconstruction if necessary +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in auto level's 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 following section of the manual to learn how to achieve the best results with double curves:\nThe Toolbox > Exposure Tab > Exposure Panel > Tone Curve +!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_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!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_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 effect of this tool or some of its sub-component is only visible at 1:1 preview scale. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Rotation anchor point X: -100=left edge, 0=center, +100=right edge +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Rotation anchor point Y: -100=top edge, 0=center, +100=bottom edge +!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 automatic exposure +!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 blown 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 simple color matrix by dcraw, enhanced RawTherapee version (whichever is available based on camera model) or embedded in 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. Use only in special cases. +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. Result can be used for calibration purposes, 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;Lab 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;Can be used with the Chromaticity slider and the CC curve. +!TP_LENSGEOM_AUTOCROP;Auto Crop +!TP_LENSGEOM_FILL;Auto fill +!TP_LENSGEOM_LABEL;Lens / Geometry +!TP_LENSPROFILE_FILEDLGFILTERLCP;Lens correction files +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;CA Correction +!TP_LENSPROFILE_USEDIST;Distortion correction +!TP_LENSPROFILE_USEVIGN;Vignetting correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset 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: 0=corners only, 50=halfway to center, 100=to center +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness: 0=rectangle, 50=fitted ellipse, 100=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. Higher = more, lower = less. +!TP_PREPROCESS_GREENEQUIL;Green Equilibration +!TP_PREPROCESS_HOTDEADPIXFILT;Hot/Dead pixel filter +!TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Try to suppress hot and dead 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_BLACKONE;Black Level: Red +!TP_RAWEXPOS_BLACKS;Black Levels +!TP_RAWEXPOS_BLACKTHREE;Black Level: Green 2 +!TP_RAWEXPOS_BLACKTWO;Black Level: Blue +!TP_RAWEXPOS_BLACKZERO;Black Level: Green 1 (lead) +!TP_RAWEXPOS_LINEAR;White Point Correction +!TP_RAWEXPOS_PRESER;Highlight Preservation +!TP_RAWEXPOS_TWOGREEN;Link greens +!TP_RAW_ALLENHANCE;Post-Demosaic Artifact/Noise Reduction +!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 +!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_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 used 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_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_ZOOMFITSCREEN;Fit 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..d1fa39fc8 --- /dev/null +++ b/rtdata/languages/Hebrew @@ -0,0 +1,1441 @@ +#01 2008-02-21 + +ADJUSTER_RESET_TO_DEFAULT;ברירת מחדל +CURVEEDITOR_FILEDLGFILTERANY;קבצים כלשהם +CURVEEDITOR_FILEDLGFILTERCURVE;קבצי עקמות +CURVEEDITOR_LINEAR;ישיר +CURVEEDITOR_LOADDLGLABEL;הטען עקמה +CURVEEDITOR_SAVEDLGLABEL;שמור עקמה +CURVEEDITOR_TOOLTIPLINEAR;החזר עקמה לישירה +CURVEEDITOR_TOOLTIPLOAD;הטען עקמה +CURVEEDITOR_TOOLTIPSAVE;שמור עקמה נוכחית +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_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_SAVEAS;שמור בשם +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_TAGGING;Tagging +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_LUMACURVE;Luminance curve +PARTIALPASTE_METAICMGROUP;Metadata/ICM settings +PARTIALPASTE_RESIZE;Resize +PARTIALPASTE_ROTATION;Rotation +PARTIALPASTE_SHADOWSHIGHLIGHTS;Shadows/Highlights +PARTIALPASTE_SHARPENING;Sharpening +PARTIALPASTE_VIGNETTING;Vignetting correction +PARTIALPASTE_WHITEBALANCE;White balance +PREFERENCES_APPLNEXTSTARTUP;ייושם באתחול הבא +PREFERENCES_BLINKCLIPPED;הבהוב באזור המקוצץ +PREFERENCES_CACHECLEARALL;Clear All +PREFERENCES_CACHECLEARPROFILES;Clear Profiles +PREFERENCES_CACHECLEARTHUMBS;Clear Thumbnails +PREFERENCES_CACHEFORMAT1;Proprietary (faster and better quality) +PREFERENCES_CACHEFORMAT2;JPEG (smaller disk footprint) +PREFERENCES_CACHEMAXENTRIES;Maximal Number of Cache Entries +PREFERENCES_CACHEOPTS;Cache Options +PREFERENCES_CACHETHUMBFORM;Cache Thumbnail Format +PREFERENCES_CACHETHUMBHEIGHT;Maximal Thumbnail Height +PREFERENCES_CLEARDLG_LINE1;Clearing cache +PREFERENCES_CLEARDLG_LINE2;This may take a few seconds. +PREFERENCES_CLEARDLG_TITLE;Please wait +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_GTKTHEME;GTK default +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_FILEDLGFILTERANY;קבצים כלשהם +PROFILEPANEL_FILEDLGFILTERPP;פרופילי עיבוד +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 שומר קובץ +PROGRESSDLG_LOADING;Loading file... +PROGRESSDLG_PROCESSING;Processing image... +PROGRESSDLG_SAVING;Saving file... +QINFO_ISO;ISO +QINFO_NOEXIF;המידע לא זמין +SAVEDLG_FILEFORMAT;תצורת קובץ +SAVEDLG_JPEGQUAL;JPEG איכות +SAVEDLG_JPGFILTER;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;שמור נתוני עיבוד עם הצילום +SAVEDLG_TIFFFILTER;TIFF קבצי +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_DEGREE;מעלות +TP_COARSETRAF_TOOLTIP_HFLIP;הפוך אופקי +TP_COARSETRAF_TOOLTIP_ROTLEFT;סובב שמאלה +TP_COARSETRAF_TOOLTIP_ROTRIGHT;סובב ימינה +TP_COARSETRAF_TOOLTIP_VFLIP;הפוך אנכי +TP_COLORBOOST_ACHANNEL;ערוץ א +TP_COLORBOOST_AMOUNT;כמות +TP_COLORBOOST_AVOIDCOLORCLIP;הימנע מקיצוץ צבע +TP_COLORBOOST_BCHANNEL;ערוץ ב +TP_COLORBOOST_CHANNEL;ערוץ +TP_COLORBOOST_CHSEPARATE;ליחוד +TP_COLORBOOST_ENABLESATLIMITER;הגבל רויה +TP_COLORBOOST_LABEL;הגברת צבע +TP_COLORBOOST_SATLIMIT;גבול רויה +TP_COLORDENOISE_EDGESENSITIVE;רגישות לקצוות +TP_COLORDENOISE_EDGETOLERANCE;סבילות לקצוות +TP_COLORDENOISE_LABEL;הסרת רעש צבעוני +TP_COLORDENOISE_RADIUS;רדיוס +TP_COLORSHIFT_BLUEYELLOW;צהוב-כחול +TP_COLORSHIFT_GREENMAGENTA;מג'נטה-ירוק +TP_COLORSHIFT_LABEL;העברת צבע +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;קבע יחס +TP_CROP_GTDIAGONALS;כלל האלכסון +TP_CROP_GTHARMMEANS1;ממוצא הרמוני 1 +TP_CROP_GTHARMMEANS2;ממוצא הרמוני 2 +TP_CROP_GTHARMMEANS3;ממוצא הרמוני 3 +TP_CROP_GTHARMMEANS4;ממוצא הרמוני 4 +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_FILEDLGFILTERANY;קבצים כלשהם +TP_ICM_FILEDLGFILTERICM;ICC קבצי צבע +TP_ICM_GAMMABEFOREINPUT;Profile applies Gamma +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_LUMACURVE_BLACKLEVEL;שחור +TP_LUMACURVE_BRIGHTNESS;בהירות +TP_LUMACURVE_COMPRHIGHLIGHTS;דחיסת גוונים בהירים +TP_LUMACURVE_COMPRSHADOWS;דחיסת גוונים כהים +TP_LUMACURVE_CONTRAST;ניגודיות +TP_LUMACURVE_CURVEEDITOR;עקמת בהירות +TP_LUMACURVE_LABEL;עקמת בהירות +TP_RAW_DMETHOD;שיטה +TP_RAW_FALSECOLOR;דחיית צבע מסולף +TP_RESIZE_BICUBICSF;ביקובי חלק +TP_RESIZE_BICUBICSH;ביקובי חד +TP_RESIZE_BICUBIC;ביקובי +TP_RESIZE_BILINEAR;בילינארי +TP_RESIZE_H;גובה +TP_RESIZE_LABEL;החלף גודל +TP_RESIZE_METHOD;שיטה +TP_RESIZE_NEAREST;הקרוב +TP_RESIZE_SCALE;מידה +TP_RESIZE_W;רוחב +TP_ROTATE_AUTOCROP;גזירה אוטומטי +TP_ROTATE_DEGREE;מעלות +TP_ROTATE_FILL;מלא +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_CURVES;Curves +!CURVEEDITOR_CURVE;Curve +!CURVEEDITOR_CUSTOM;Custom +!CURVEEDITOR_DARKS;Darks +!CURVEEDITOR_HIGHLIGHTS;Highlights +!CURVEEDITOR_LIGHTS;Lights +!CURVEEDITOR_MINMAXCPOINTS;Minima/Maxima control points +!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 +!EXIFFILTER_EXPOSURECOMPENSATION;Exposure Compensation (EV) +!EXIFFILTER_FILETYPE;File Type +!EXIFFILTER_METADATAFILTER;Enable Metadata Filters +!EXPORT_BYPASS_ALL;Select / Unselect All +!EXPORT_BYPASS_COLORDENOISE;Bypass Color denoise +!EXPORT_BYPASS_DEFRINGE;Bypass Defringe +!EXPORT_BYPASS_DIRPYRDENOISE;Bypass Noise Reduction +!EXPORT_BYPASS_DIRPYREQUALIZER;Bypass Contrast by Detail Levels +!EXPORT_BYPASS_LUMADENOISE;Bypass Luma denoise +!EXPORT_BYPASS_RAW_ALL_ENHANCE;Bypass Post Demosaic Artifact/Noise Reduction +!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 +!EXPORT_RESIZEMETHOD;Resize 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.\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\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_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_POPUPRANK;Rank +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!FILEBROWSER_QUERYHINT;Type a partial filename to search for or a comma-separated list.\nE.g. 1001,1004,1199 \n\nCtrl-F to focus to the Find text box.\nEnter to commence search.\nEsc to clear.\nShift-Esc to remove focus. +!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.\nShortcut: i\n\nShortcut in Single Editor Tab Mode: Alt-i +!FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show images recently saved.\nShortcut: Alt-7 +!FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show images not recently saved.\nShortcut: Alt-6 +!FILEBROWSER_SHOWUNCOLORHINT;Show images without Color label.\nShortcut: Alt-0 +!FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +!FILEBROWSER_UNRANK_TOOLTIP;Unrank\nShortcut: Shift-0 +!FILEBROWSER_USETEMPLATE;Use template: +!GENERAL_AFTER;After +!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\nClick right mouse button on image preview to freeze/unfreeze +!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram +!HISTOGRAM_TOOLTIP_FULL;Toggle full (on) or scaled (off) 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;Lab - Chromaticity +!HISTORY_MSG_96;'a' Curve +!HISTORY_MSG_97;'b' Curve +!HISTORY_MSG_98;Demosaicing Method +!HISTORY_MSG_99;Hot/Dead pixel filter +!HISTORY_MSG_100;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;Resizing applies to +!HISTORY_MSG_111;Lab - Avoid color shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;Lab - Protection +!HISTORY_MSG_114;DCB Iterations +!HISTORY_MSG_115;False Color Suppression +!HISTORY_MSG_116;DCB Enhancement +!HISTORY_MSG_117;Raw Red CA Correction +!HISTORY_MSG_118;Raw Blue CA Correction +!HISTORY_MSG_119;Line Noise Filter +!HISTORY_MSG_120;Green Equilibration +!HISTORY_MSG_121;Raw Auto CA +!HISTORY_MSG_122;Dark Frame Auto Select +!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 Select +!HISTORY_MSG_128;Flat Field Blur Radius +!HISTORY_MSG_129;Flat Field Blur Type +!HISTORY_MSG_130;Auto Distorion +!HISTORY_MSG_131;Noise Reduction Luma +!HISTORY_MSG_132;Noise Reduction 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;Edges Sharpening +!HISTORY_MSG_147;ES - Luminance Only +!HISTORY_MSG_148;Microcontrast +!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_150;Post Demosaic Artifact/Noise Reduction +!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;'CC' curve +!HISTORY_MSG_169;'CH' curve +!HISTORY_MSG_170;Vib - Curve +!HISTORY_MSG_171;'LC' curve +!HISTORY_MSG_172;Lab - 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 tones protection +!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 pixels +!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;'CL' curve +!HISTORY_MSG_247;'LH' curve +!HISTORY_MSG_248;'HH' curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +!MAIN_BUTTON_FULLSCREEN;Fullscreen +!MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the Next image relative to image open in Editor\nShortcut: Shift-F4\n\nTo navigate to the Next image relative to thumbnail selected in File Browser\nShortcut: F4 +!MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the Previous image relative to image open in Editor\nShortcut: Shift-F3 \n\nTo navigate to the Previous image relative to thumbnail selected in File Browser\nShortcut: F3 +!MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronize the File Browser with the Editor to reveal the thumbnail of the currently open image, and clear filters in File Browser \nShortcut: x\n\nAs above, but without clearing filters in File Browser\nShortcut: y\n(Note that thumbnail of the open file 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\ndoesn't exist. Please set a correct path in the Preference window. +!MAIN_MSG_SETPATHFIRST;You have to set a target path first in Preferences\nin order to use this function! +!MAIN_MSG_WRITEFAILED;Failed to write\n\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_METADATA_TOOLTIP;Shortcut: Alt-m +!MAIN_TAB_RAW;Raw +!MAIN_TAB_RAW_TOOLTIP;Shortcut: Alt-r +!MAIN_TAB_TRANSFORM_TOOLTIP;Shortcut: Alt-t +!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 10-30%\n\nPreview is rendered slower with Focus Mask turned on. +!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_NA;B = n/a +!NAVIGATOR_B_VALUE;B = %1 +!NAVIGATOR_G_NA;G = n/a +!NAVIGATOR_G_VALUE;G = %1 +!NAVIGATOR_H_NA;H = n/a +!NAVIGATOR_H_VALUE;H = %1 +!NAVIGATOR_LAB_A_NA;a = n/a +!NAVIGATOR_LAB_A_VALUE;a = %1 +!NAVIGATOR_LAB_B_NA;b = n/a +!NAVIGATOR_LAB_B_VALUE;b = %1 +!NAVIGATOR_LAB_L_NA;L = n/a +!NAVIGATOR_LAB_L_VALUE;L = %1 +!NAVIGATOR_R_NA;R = n/a +!NAVIGATOR_R_VALUE;R = %1 +!NAVIGATOR_S_NA;S = n/a +!NAVIGATOR_S_VALUE;S = %1 +!NAVIGATOR_V_NA;V = n/a +!NAVIGATOR_V_VALUE;V = %1 +!NAVIGATOR_XY_FULL;Width = %1, Height = %2 +!NAVIGATOR_XY_NA;x = n/a, y = n/a +!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;CIE Color Appearance Model 2002 +!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_EVERYTHING;Everything +!PARTIALPASTE_FLATFIELDAUTOSELECT;Flat field auto selection +!PARTIALPASTE_FLATFIELDBLURRADIUS;Flat field blur radius +!PARTIALPASTE_FLATFIELDBLURTYPE;Flat field blur type +!PARTIALPASTE_FLATFIELDFILE;Flat field file +!PARTIALPASTE_GRADIENT;Graduated filter +!PARTIALPASTE_HSVEQUALIZER;HSV equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!PARTIALPASTE_LABCURVE;Lab adjustments +!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_PERSPECTIVE;Perspective +!PARTIALPASTE_PREPROCESS_GREENEQUIL;Green equilibration +!PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Apply hot/dead 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_ALLENHANCE;Post-demosaic artifact/noise reduction +!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 +!PREFERENCES_ADD;Add +!PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!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_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_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 scipts 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_DATEFORMATFRAME;Date Format +!PREFERENCES_DIRDARKFRAMES;Dark frames directory +!PREFERENCES_EDITORLAYOUT;Editor Layout +!PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar (de-select for low resolution display) +!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_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;Output device's Yb luminance (%) +!PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogram in left panel +!PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Show embedded JPEG thumbnail if raw is unedited +!PREFERENCES_LANGAUTODETECT;Use OS language setting +!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_MULTITABDUALMON;Multiple Editor Tabs Mode (if available on second monitor) +!PREFERENCES_MULTITAB;Multiple Editor Tabs Mode +!PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails +!PREFERENCES_OVERWRITEOUTPUTFILE;Overwrite existing output files +!PREFERENCES_PANFACTORFRAME;Pan Rate Amplification +!PREFERENCES_PANFACTORLABEL;Factor +!PREFERENCES_PROPERTY;Property +!PREFERENCES_RGBDTL_LABEL;Max number of threads for Noise Reduction +!PREFERENCES_RGBDTL_TOOLTIP;Noise Reduction requires a baseline of about 128MB RAM for a 10MPix image or 512MB for a 40MPix image, and additionally 128MB RAM per thread. The more threads run in parallel, the faster the computation. Leave the setting at "0" to automatically use as many threads as possible. +!PREFERENCES_SELECTFONT;Select font +!PREFERENCES_SET;Set +!PREFERENCES_SHOWEXPOSURECOMPENSATION;Append exposure compensation +!PREFERENCES_SHOWPROFILESELECTOR;Show processing profile selector +!PREFERENCES_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs +!PREFERENCES_SINGLETAB;Single Editor Tab Mode +!PREFERENCES_SLIMUI;Slim interface +!PREFERENCES_SND_BATCHQUEUEDONE;Queue processing done +!PREFERENCES_SND_HELP;Either enter filepath or nothing (for no sound).\nOn Windows use "SystemDefault", "SystemAsterisk" etc. for system sounds.\nOn Linux use "complete", "window-attention" etc. for system sounds. +!PREFERENCES_SND_LNGEDITPROCDONE;Editor processing done +!PREFERENCES_SND_TRESHOLDSECS;after secs +!PREFERENCES_SQUAREDETAILWINDOW;Square detail window (faster) +!PREFERENCES_TAB_PERFORMANCE;Performance +!PREFERENCES_TAB_SOUND;Sounds +!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_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_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing channel-mixer +!TP_BWMIX_BLUE;Blue +!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;Modify luminance in function of hue\nPay attention to extreme values that may cause artifacts +!TP_BWMIX_CYAN;Cyan +!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 simulate shots taken with a colored filter placed in front of the lens. Colored filters reduce transmission of specific range of colors and correspondingly affect their lightness. E.g. a Red filter darkens Blue skies. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_BLUE;Blue Channel +!TP_BWMIX_GAM_GREEN;Green Channel +!TP_BWMIX_GAM_RED;Red Channel +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each channel RGB +!TP_BWMIX_GREEN;Green +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MAGENTA;Magenta +!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 (filter, channel-mixer) to default +!TP_BWMIX_ORANGE;Orange +!TP_BWMIX_PURPLE;Purple +!TP_BWMIX_RED;Red +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all of the mixer options\nTotal displays the sum of RGB values actually applied:\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 (films, landscape, ...) or manual settings of channel-mixer +!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;Channel-Mixer absolute RGB +!TP_BWMIX_SET_RGBREL;Channel-Mixer relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Channel-Mixer absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Channel-Mixer 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_BWMIX_YELLOW;Yellow +!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) RT 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.\n 0=no effect 1=median 2=gaussian.\n\nThese artifacts are due to limitations of CIECAM02. Alternatively, adjust the image to avoid very dark shadows. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from Lab and RGB brightness +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from Lab and RGB colorfulness +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from Lab and RGB saturation +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from Lab 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 Lab and RGB contrast +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from Lab and RGB contrast +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L (Lab) 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 (Lab) 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 Lab values before CIECAM02 adjustments +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RT 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 (Lab) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in Lab 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 Lab and RGB lightness +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model\n\nWB [RT] + [output]:\nRT's white balance is used for the scene, CIECAM02 is set to D50, the output device's white balance is set in Preferences > Color Management\n\nWB [RT+CAT02] + [output]:\nRT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences +!TP_COLORAPP_RSTPRO;Red & skin tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin tones protection (sliders and curves) +!TP_COLORAPP_SHARPCIE;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe with Q/C +!TP_COLORAPP_SHARPCIE_TOOLTIP;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe will use CIECAM02 if enabled. +!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;Change tones and colors to take into account the viewing conditions of the output device\n\nAverage:\nAverage light environment (standard)\nThe image will not change\n\nDim:\nDim environment (TV)\nThe image will become slighty dark\n\nDark:\nDark environment (projector)\nThe image will become more dark\n\nExtremly Dark:\nExtremly dark environment (cutsheet)\nThe image will become very dark +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if source 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 Lab 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_CROP_GTEPASSPORT;Biometric Passport +!TP_CROP_GTFRAME;Frame +!TP_CROP_GTGRID;Grid +!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_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_CHROMA;Chrominance - Master +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on gamma of the input color profile. Gamma of sRGB is assumed, thus if input image is in color profile of a different gamma, luminance noise reduction will vary. +!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_LAB;Lab +!TP_DIRPYRDENOISE_LDETAIL;Luminance Detail +!TP_DIRPYRDENOISE_LUMA;Luminance +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or Lab methods can be used.\n\nFor non-raw images Lab method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_PERF;RGB mode (raw images) +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGB;RGB +!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_THRESHOLD;Threshold +!TP_DISTORTION_AUTO;Auto Distortion Correction +!TP_DISTORTION_AUTO_TIP;(Exprimental) Correct lens distortion automatically for some cameras (Micro 4/3, some compact digital cameras, etc.) +!TP_EPD_EDGESTOPPING;Edge Stopping +!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 via Lab mode (standard) and CIECAM02 mode.\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_EXPOSCORR_LABEL;Raw White & Black Points +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggle execution of auto levels to automatically set parameter values based on image analysis\nEnable Highlight Reconstruction if necessary +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in auto level's 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 following section of the manual to learn how to achieve the best results with double curves:\nThe Toolbox > Exposure Tab > Exposure Panel > Tone Curve +!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_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!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_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 effect of this tool or some of its sub-component is only visible at 1:1 preview scale. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Rotation anchor point X: -100=left edge, 0=center, +100=right edge +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Rotation anchor point Y: -100=top edge, 0=center, +100=bottom edge +!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 automatic exposure +!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 blown 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 simple color matrix by dcraw, enhanced RawTherapee version (whichever is available based on camera model) or embedded in 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. Use only in special cases. +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. Result can be used for calibration purposes, 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;Lab 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;Can be used with the Chromaticity slider and the CC curve. +!TP_LENSGEOM_AUTOCROP;Auto Crop +!TP_LENSGEOM_FILL;Auto fill +!TP_LENSGEOM_LABEL;Lens / Geometry +!TP_LENSPROFILE_FILEDLGFILTERLCP;Lens correction files +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;CA Correction +!TP_LENSPROFILE_USEDIST;Distortion correction +!TP_LENSPROFILE_USEVIGN;Vignetting correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset 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: 0=corners only, 50=halfway to center, 100=to center +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness: 0=rectangle, 50=fitted ellipse, 100=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. Higher = more, lower = less. +!TP_PREPROCESS_GREENEQUIL;Green Equilibration +!TP_PREPROCESS_HOTDEADPIXFILT;Hot/Dead pixel filter +!TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Try to suppress hot and dead 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_BLACKONE;Black Level: Red +!TP_RAWEXPOS_BLACKS;Black Levels +!TP_RAWEXPOS_BLACKTHREE;Black Level: Green 2 +!TP_RAWEXPOS_BLACKTWO;Black Level: Blue +!TP_RAWEXPOS_BLACKZERO;Black Level: Green 1 (lead) +!TP_RAWEXPOS_LINEAR;White Point Correction +!TP_RAWEXPOS_PRESER;Highlight Preservation +!TP_RAWEXPOS_TWOGREEN;Link greens +!TP_RAW_ALLENHANCE;Post-Demosaic Artifact/Noise Reduction +!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 +!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_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 used 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_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_ZOOMFITSCREEN;Fit 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..0a3521af6 --- /dev/null +++ b/rtdata/languages/Italiano @@ -0,0 +1,1410 @@ +#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 2013-03-21 v4.0 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_FILEDLGFILTERANY;Qualsiasi file +CURVEEDITOR_FILEDLGFILTERCURVE;File di curve +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: +EDITWINDOW_TITLE;Modifica immagine +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_COLORDENOISE;Ignora Riduzione del Rumore di Crominanza +EXPORT_BYPASS_DEFRINGE;Ignora Defringe +EXPORT_BYPASS_DIRPYRDENOISE;Ignora Riduzione Rumore +EXPORT_BYPASS_DIRPYREQUALIZER;Ignora Contrasto per livelli di dettaglio +EXPORT_BYPASS_LUMADENOISE;Ignora Riduzione Rumore di Luminanza +EXPORT_BYPASS_RAW_ALL_ENHANCE;Ignora Riduzione Rumore/Artefatti di Demosaic. +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_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 +EXPORT_RESIZEMETHOD;Metodo di Ridimensionamento +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 del programma +FILEBROWSER_CLEARPROFILE;Cancella +FILEBROWSER_COPYPROFILE;Copia +FILEBROWSER_CURRENT_NAME;Nome corrente: +FILEBROWSER_DARKFRAME;Dark Frame +FILEBROWSER_DELETEDLGLABEL;Conferma eliminazione del file +FILEBROWSER_DELETEDLGMSGINCLPROC;Sei certo di voler eliminare i %1 file INCLUSA la versione sviluppata nella coda? +FILEBROWSER_DELETEDLGMSG;Sei certo di voler 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_POPUPCOLORLABEL;Etichetta colorata +FILEBROWSER_POPUPCOPYTO;Copia in... +FILEBROWSER_POPUPFILEOPERATIONS;Operazioni sui file +FILEBROWSER_POPUPMOVEEND;Sposta in fondo alla coda +FILEBROWSER_POPUPMOVEHEAD;Sposta in cima alla coda +FILEBROWSER_POPUPMOVETO;Sposta in... +FILEBROWSER_POPUPOPEN;Apri +FILEBROWSER_POPUPPROCESSFAST;Aggiungi alla Coda (Esportazione Rapida) +FILEBROWSER_POPUPPROCESS;Aggiungi alla Coda +FILEBROWSER_POPUPPROFILEOPERATIONS;Operazioni sui Profili di Sviluppo +FILEBROWSER_POPUPRANK;Classificazione +FILEBROWSER_POPUPREMOVEINCLPROC;Elimina (assieme a quanto sviluppato nella coda) +FILEBROWSER_POPUPREMOVE;Elimina +FILEBROWSER_POPUPRENAME;Rinomina +FILEBROWSER_POPUPSELECTALL;Seleziona tutto +FILEBROWSER_POPUPTRASH;Sposta nel cestino +FILEBROWSER_POPUPUNRANK;Declassifica +FILEBROWSER_POPUPUNTRASH;Rimuovi dal cestino +FILEBROWSER_QUERYBUTTONHINT;Azzera la ricerca +FILEBROWSER_QUERYHINT;Scrivi una parte del nome del file da cercare o una lista separata da virgole\nEsempio: 1001,1004,1199\n\nCtrl-f per selezionare la parola (solo nel Navigatore);\nInvio per avviare la ricerca\nEsc<\b> per cancellare. +FILEBROWSER_QUERYLABEL; Cerca: +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 D +FILEBROWSER_SHOWEDITEDHINT;Mostra immagini modificate.\nScorciatoia: 7 +FILEBROWSER_SHOWEDITEDNOTHINT;Mostra immagini non modificate.\nScorciatoia: 6 +FILEBROWSER_SHOWEXIFINFO;Mostra informazioni EXIF.\nScorciatoia: i +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 di recente.\nScorciatoia: Alt-7 +FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Mostra le immagini salvate non di recente.\nScorciatoia: Alt-6 +FILEBROWSER_SHOWTRASHHINT;Mostra il contenuto del cestino.\nScorciatoia: 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;Smetti di sviluppare +FILEBROWSER_THUMBSIZE;Dimensione miniature +FILEBROWSER_TOOLTIP_STOPPROCESSING;Inizia a sviluppare automaticamente quando un nuovo lavoro viene accodato +FILEBROWSER_USETEMPLATE;Segui lo schema: +FILEBROWSER_ZOOMINHINT;Aumenta la dimensione delle miniature.\nScorciatoia: + +FILEBROWSER_ZOOMOUTHINT;Diminuisci la dimensione delle miniature.\nScorciatoia: - +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/d +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 o scalato +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;Profilo caricato +HISTORY_MSG_3;Profilo 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;Esposizione automatica +HISTORY_MSG_13;Tosaggio Esposizione +HISTORY_MSG_14;Luminanza: Luminosità +HISTORY_MSG_15;Luminanza: 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;Nitidezza - Raggio +HISTORY_MSG_22;Nitidezza - Quantità +HISTORY_MSG_23;Nitidezza - Soglia +HISTORY_MSG_24;Definisci solo i bordi +HISTORY_MSG_25;Nitidezza - Raggio di rilevamento bordi +HISTORY_MSG_26;Nitidezza - Tolleranza bordi +HISTORY_MSG_27;Nitidezza - Controllo alone +HISTORY_MSG_28;Quantità Controllo alone +HISTORY_MSG_29;Nitidezza - Metodo +HISTORY_MSG_30;Deconvoluzione - Raggio +HISTORY_MSG_31;Deconvoluzione - Quantità +HISTORY_MSG_32;Deconvoluzione - Smorzamento +HISTORY_MSG_33;Deconvoluzione - 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;Bilanciamento del bianco - Metodo +HISTORY_MSG_39;Temperatura colore +HISTORY_MSG_40;Bilanciamento del bianco - 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 luminanza - Raggio +HISTORY_MSG_45;Rid. rumore luminanza - 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;Rid. rumore crominanza - Sensibilità bordi +HISTORY_MSG_50;Ombre/Alteluci +HISTORY_MSG_51;Alteluci +HISTORY_MSG_52;Ombre +HISTORY_MSG_53;Ampiezza tonale - Alteluci +HISTORY_MSG_54;Ampiezza tonale - Ombre +HISTORY_MSG_55;Contrasto locale +HISTORY_MSG_56;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 dell'Obiettivo +HISTORY_MSG_63;Istantanea selezionata +HISTORY_MSG_64;Ritaglia +HISTORY_MSG_65;Correzione Aberrazioni Cromatiche +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 +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;Alta qualità Ombre/Alteluci +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 +HISTORY_MSG_90;Riduzione Rumore - Luminanza +HISTORY_MSG_91;Riduzione Rumore - Crominanza +HISTORY_MSG_92;Riduzione Rumore - Gamma +HISTORY_MSG_93;Contrasto per livelli di dettaglio - Valore +HISTORY_MSG_94;Contrasto per livelli di dettaglio +HISTORY_MSG_95;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;Eq. HSV - Tonalità +HISTORY_MSG_102;Eq. HSV - Saturazione +HISTORY_MSG_103;Eq. HSV - Valore +HISTORY_MSG_104;Equalizzatore HSV +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;Previeni color shift +HISTORY_MSG_112;--inutilizzato-- +HISTORY_MSG_113;Protezione toni rossi e incarnato +HISTORY_MSG_114;Iterazioni DCB +HISTORY_MSG_115;Stadi per 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 - Soglia +HISTORY_MSG_121;AC automatica (Raw) +HISTORY_MSG_122;Dark Frame - Automatico +HISTORY_MSG_123;Dark Frame - File +HISTORY_MSG_124;Compensazione esp. lineare +HISTORY_MSG_125;Comp. di 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 +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;Nitidezza ai Bordi - Iterazioni +HISTORY_MSG_143;Nitidezza ai Bordi - Quantità +HISTORY_MSG_144;Microcontrasto - Quantità +HISTORY_MSG_145;Microcontrasto - Uniformità +HISTORY_MSG_146;Nitidezza ai Bordi +HISTORY_MSG_147;Nitidezza ai Borid - Solo luminanza +HISTORY_MSG_148;Microcontrasto +HISTORY_MSG_149;Microcontrasto - Matrice 3x3 +HISTORY_MSG_150;Riduzione 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 e Saturi +HISTORY_MSG_157;Vividezza - Soglia Pastello/Saturi +HISTORY_MSG_158;Forza +HISTORY_MSG_159;Blocco ai Bordi +HISTORY_MSG_160;Scala +HISTORY_MSG_161;Iterazioni di Ribilanciamento +HISTORY_MSG_162;Tone Mapping +HISTORY_MSG_163;Curve RGB - R +HISTORY_MSG_164;Curve RGB - G +HISTORY_MSG_165;Curve RGB - B +HISTORY_MSG_166;Livelli Neutrali +HISTORY_MSG_167;Viraggio B&W +HISTORY_MSG_168;Curva 'CC' +HISTORY_MSG_169;Curva 'CH' +HISTORY_MSG_170;Vividezza - Curva +HISTORY_MSG_171;Curva 'LC' +HISTORY_MSG_172;Limita LC ai toni rossi e incarnato +HISTORY_MSG_173;Riduzione Rumore - Dettaglio di Luminanza +HISTORY_MSG_174;CIECAM02 +HISTORY_MSG_175;CAM02 - Quantità di Adattamento Croma +HISTORY_MSG_176;CAM02 - Ambiente di Visualizzazione +HISTORY_MSG_177;CAM02 - Adattamento Lum. della scena +HISTORY_MSG_178;CAM02 - Adattamento Lum. della vis. +HISTORY_MSG_179;CAM02 - Modello +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 - Scena con ambiente buio +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 (angolo) +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 CIECAM negli istogrammi +HISTORY_MSG_200;CAM02 - Tone mapping con CIECAM02 Q +HISTORY_MSG_201;Riduzione Rumore - Delta Crominanza Rosso +HISTORY_MSG_202;Riduzione Rumore - Delta Crominanza Blu +HISTORY_MSG_203;Riduzione Rumore - Metodo +HISTORY_MSG_204;Passaggi di miglioramento LMMSE +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;Individua l'immagine successiva rispetto a un'immagine aperta per la Modifica\nScorciatoia: Shift-F4\n\nPer passare alla successiva immagine relativa alla miniatura selezionata nel Navigatore\nScorciatoia: F4 +MAIN_BUTTON_NAVPREV_TOOLTIP;Individua l'immagine precedente rispetto a un'immagine aperta per la Modifica\nScorciatoia: Shift-F3\n\nPer passare all'immagine precedente relativa alla miniatura selezionata in Navigate\nScorciatoia: F3 +MAIN_BUTTON_NAVSYNC_TOOLTIP;Sincronizza il Navigatore con la scheda di Modifica per rivelare la miniatura dell'immagine attualmente aperta, e rimuovere i filtri nel Navigatore\nScorciatoia: x\n\nCome sopra, ma senza cancellare i filtri nel Navigatore\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;Il file esiste già! +MAIN_MSG_CANNOTLOAD;Impossibile caricare l'immagine +MAIN_MSG_CANNOTSAVE;Errore nel salvare il 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;Intendi 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; Esporta +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_TAGGING;Etichettatura +MAIN_TAB_TRANSFORM;Trasformazione +MAIN_TAB_TRANSFORM_TOOLTIP;Scorciatoia: Alt-t +MAIN_TOOLTIP_BACKCOLOR0;Colore di sfondo dell'anteprima: Basato sul tema\nScorciatoia: 8 +MAIN_TOOLTIP_BACKCOLOR1;Colore di sfondo dell'anteprima: Nero\nScorciatoia: 9 +MAIN_TOOLTIP_BACKCOLOR2;Colore di sfondo dell'anteprima: Bianco\nScorciatoia: 0 +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 fatti paragoni con ogni passo 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: H +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%.\n\nIl calcolo dell'anteprima viene rallentato con la Focus Mask attivata. +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_NA;B = n/d +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_G_NA;G = n/d +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_H_NA;H = n/d +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_LAB_A_NA;a = n/d +NAVIGATOR_LAB_A_VALUE;a = %1 +NAVIGATOR_LAB_B_NA;b = n/d +NAVIGATOR_LAB_B_VALUE;b = %1 +NAVIGATOR_LAB_L_NA;L = n/d +NAVIGATOR_LAB_L_VALUE;L = %1 +NAVIGATOR_R_NA;R = n/d +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_S_NA;S = n/d +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_NA;V = n/d +NAVIGATOR_V_VALUE;V = %1 +NAVIGATOR_XY_FULL;Larghezza = %1, Altezza = %2 +NAVIGATOR_XY_NA;x = n/d, y = n/d +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_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;Autoseleziona Dark Frame +PARTIALPASTE_DARKFRAMEFILE;Fotogramma di Fondo (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;FF - Autoselezione +PARTIALPASTE_FLATFIELDBLURRADIUS;FF - Raggio di sfocamento +PARTIALPASTE_FLATFIELDBLURTYPE;FF - Modalità di sfocamento +PARTIALPASTE_FLATFIELDFILE;File Flat Field (FF) +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_METAICMGROUP;Impostazioni di metadati e Gestione Colore +PARTIALPASTE_PERSPECTIVE;Prospettiva +PARTIALPASTE_PREPROCESS_GREENEQUIL;Bilanciamento del verde +PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Filtro dei pixel surriscaldati/guasti +PARTIALPASTE_PREPROCESS_LINEDENOISE;Filtro per rumore a bande +PARTIALPASTE_RAWCACORR_AUTO;Autocorrezione AC +PARTIALPASTE_RAWCACORR_CABLUE;Correzione AC blu +PARTIALPASTE_RAWCACORR_CARED;Correzione AC rossa +PARTIALPASTE_RAWEXPOS_BLACK;Punto del Nero +PARTIALPASTE_RAWEXPOS_LINEAR;Punto del Bianco: fattore di comp. lineare +PARTIALPASTE_RAWEXPOS_PRESER;Punto del Bianco: compensazione (EV) preservante le alteluci +PARTIALPASTE_RAWGROUP;Impostazioni del Raw +PARTIALPASTE_RAW_ALLENHANCE;Limita rumore/artefatti dovuti alla demosaicizzazione +PARTIALPASTE_RAW_DCBENHANCE;Fase di miglioramento per 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 (MDC/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_BLINKCLIPPED;Lampeggia le aree tosate +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 del programma +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.\nRisponde a parametri da linea di commando per permettere di generare profili basati su regole quali:\n[Percorso del Raw/JPG] [Percorso del profilo predefinito] [numero-f] [esposizione in secondi] [focale in mm] [ISO] [Obiettivo] [Fotocamera] +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;Presenti +PREFERENCES_DARKFRAMESHOTS;fotogrammi +PREFERENCES_DARKFRAMETEMPLATES;modelli +PREFERENCES_DARKFRAME;Dark Frame +PREFERENCES_DATEFORMATFRAME;Formato della data +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;Programmi 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;Presenti +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 file 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_GTKTHEME;Predefinito GTK +PREFERENCES_HISTOGRAMPOSITIONLEFT;Istogramma nel pannello sinistro +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" +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_OUTDIRFOLDERHINT;Mette le immagini salvate 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\nSe vuoi salvare l'immagine finale nella stessa posizione dove si trova l'originale, scrivi:\n%p1/%f\n\nSe vuoi salvare l'immagine finale in una cartella chiamata "sviluppate" situata nella cartella degli originali, scrivi:\n%p1/sviluppate/%f\n\nSe intendi salvare l' +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_PANFACTORFRAME;Accelerazione nello scorrimento +PREFERENCES_PANFACTORLABEL;Fattore +PREFERENCES_PARSEDEXTADDHINT;Immetti l'estensione e premi questo tasto per aggiungerla 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 del programma +PREFERENCES_PROFILEPRFILE;Profilo a fianco del file originario +PREFERENCES_PROFILESAVECACHE;Salva il profilo di sviluppo nella memoria del programma +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 un carattere +PREFERENCES_SELECTLANG;Seleziona la lingua +PREFERENCES_SELECTTHEME;Seleziona un tema +PREFERENCES_SET;Imposta +PREFERENCES_SHOWBASICEXIF;Mostra dati Exif di base +PREFERENCES_SHOWDATETIME;Mostra data e ora +PREFERENCES_SHOWEXPOSURECOMPENSATION;Accoda compensazione dell'esposizione +PREFERENCES_SHOWPROFILESELECTOR;Mostra il selettore di profilo di sviluppo +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_SQUAREDETAILWINDOW;Finestra di dettaglio quadrata (più rapida) +PREFERENCES_STARTUPIMDIR;Cartella delle immagini all'avvio +PREFERENCES_TAB_BROWSER;Navigatore di file +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_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_FILEDLGFILTERANY;Qualsiasi file +PROFILEPANEL_FILEDLGFILTERPP;Profili di sviluppo +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 a livello di codice.\n\nPulsante rilasciato: i Profili saranno applicati così come sono, modificando solo i valori che contengono. +PROFILEPANEL_PASTEPPASTE;Parametri da incollare +PROFILEPANEL_PCUSTOM;Personalizzato +PROFILEPANEL_PFILE;Da file +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 delle miniature... +PROGRESSBAR_LOADING;Caricamento dell'immagine... +PROGRESSBAR_LOADJPEG;Caricamento del file JPEG... +PROGRESSBAR_LOADPNG;Caricamento del file PNG... +PROGRESSBAR_LOADTIFF;Caricamento del file 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_JPGFILTER;File 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 assieme all'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_TIFFFILTER;File TIFF +SAVEDLG_TIFFUNCOMPRESSED;TIFF non compresso +SAVEDLG_WARNFILENAME;Il file verrà chiamato +SHCSELECTOR_TOOLTIP;Tasto destro del mouse per ripristinare\nla 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 +TOOLBAR_TOOLTIP_HAND;Strumento mano.\nScorciatoia: h +TOOLBAR_TOOLTIP_STRAIGHTEN;Linea dritta/Rotazione Precisa.\nScorciatoia: s\n\nTraccia il verticale o l'orizzontale tracciando una linea guida 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_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.\nScorciatoia: [ +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Ruota a destra.\nScorciatoia: ] +TP_COARSETRAF_TOOLTIP_VFLIP;Rifletti verticalmente +TP_COLORAPP_ADAPTSCENE;Adattamento luminanza della scena (cd/m2) +TP_COLORAPP_ADAPTSCENE_TOOLTIP;Luminanza assoluta dell'ambiente della scena\n(normalmente 2000cd/m2) +TP_COLORAPP_ADAPTVIEWING;Adattamento luminanza di visualizzazione (cd/m2) +TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Luminanza assoluta dell'ambiente di visualizzazione\n(normalmente 16cd/m2) +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_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;WB [RT] + [output]:\nPer la scena viene usato il Bilanciamento del Bianco di RT, CIECAM02 è impostato a D50, il bianco del dispositivo di uscita utilizza il valore impostato nelle Preferenze.\n\nWB [RT+CAT02] + [output]:\nLe impostazioni di Bilanciamento del Bianco di RT sono utilizzate da CAT02 e il bianco del dispositivo di uscita utilizza il valore impostato nelle preferenze. +TP_COLORAPP_RSTPRO;Protezione rossi e incarnato +TP_COLORAPP_RSTPRO_TOOLTIP;Protezione dei toni rossi e dell'incarnato (cursori e curve) +TP_COLORAPP_SHARPCIE;Nitidezza, Contrasto per livelli di Dettaglio, Microcontrasto e Defringe con Q/C +TP_COLORAPP_SHARPCIE_TOOLTIP;Nitidezza, Contrasto per livelli di dettaglio, Microcontrasto e Defringe useranno CIECAM02 se abilitato. +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 Brillanza (Q) 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_GTHARMMEANS1;Media armonica 1 +TP_CROP_GTHARMMEANS2;Media armonica 2 +TP_CROP_GTHARMMEANS3;Media armonica 3 +TP_CROP_GTHARMMEANS4;Media armonica 4 +TP_CROP_GTNONE;Nessuna +TP_CROP_GTRULETHIRDS;Regola dei terzi +TP_CROP_GUIDETYPE;Tipo di guida: +TP_CROP_H;A +TP_CROP_LABEL;Ritaglia +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 (Lab/CIECAM02) +TP_DEFRINGE_RADIUS;Raggio +TP_DEFRINGE_THRESHOLD;Soglia +TP_DIRPYRDENOISE_BLUE;Delta di Crominanza - Blu +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_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_PERF;Modo RGB (immagini raw) +TP_DIRPYRDENOISE_RED;Delta di Crominanza - Rosso +TP_DIRPYRDENOISE_RGB;RGB +TP_DIRPYREQUALIZER_LABEL;Contrasto per livelli di dettaglio (Lab/CIECAM02) +TP_DIRPYREQUALIZER_LUMACOARSEST;Estesissimo +TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS;Contrasto- +TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS;Contrasto+ +TP_DIRPYREQUALIZER_LUMAFINEST;Finissimo +TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutro +TP_DIRPYREQUALIZER_THRESHOLD;Soglia +TP_DISTORTION_AMOUNT;Quantità +TP_DISTORTION_AUTO; Autocorrezione Distorsione +TP_DISTORTION_AUTO_TIP;(Sperimentale) 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 (Lab/CIECAM02) +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 Brillanza Q CIECAM" +TP_EXPOSCORR_LABEL;Punti Bianco e Nero del Raw +TP_EXPOSURE_AUTOLEVELS;Livelli automatici +TP_EXPOSURE_AUTOLEVELS_TIP;Abilita l'esecuzione dei livelli automatici per impostare automaticamente i valori dei parametri in base all'analisi dell'immagine +TP_EXPOSURE_BLACKLEVEL;Livello del nero +TP_EXPOSURE_BRIGHTNESS;Luminosità +TP_EXPOSURE_CLIP;Tosa +TP_EXPOSURE_CLIP_TIP;La frazione di pixel da tosare nell'operazione di livelli automatici +TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Soglia di Recupero Alteluci +TP_EXPOSURE_COMPRHIGHLIGHTS;Recupero Alteluci +TP_EXPOSURE_COMPRSHADOWS;Recupero Ombre +TP_EXPOSURE_CONTRAST;Contrasto +TP_EXPOSURE_CURVEEDITOR1;Curva Tono 1 +TP_EXPOSURE_CURVEEDITOR2;Curva Tono 2 +TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Fare riferimento alla seguente sezione del manuale per capire come ottenere i risultati migliori con le doppie curve:\nScheda Esposizione > Esposizione > Curva Tono +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_HLREC_BLEND;Fusione +TP_HLREC_CIELAB;Fusione in CIELab +TP_HLREC_COLOR;Propagazione di crominanza +TP_HLREC_LABEL;Ricostruzione Alteluci +TP_HLREC_LUMINANCE;Recupero di Luminanza +TP_HLREC_METHOD;Metodo: +TP_HSVEQUALIZER_CHANNEL;Canale HSV +TP_HSVEQUALIZER_HUE;H +TP_HSVEQUALIZER_LABEL;Equalizzatore HSV +TP_HSVEQUALIZER_SAT;S +TP_HSVEQUALIZER_VAL;V +TP_ICM_BLENDCMSMATRIX;Miscela le alteluci ICC con matrix +TP_ICM_BLENDCMSMATRIX_TOOLTIP;Abilita per recuperare le alteluci bruciate quando usi profili ICC basati su LUT +TP_ICM_FILEDLGFILTERANY;Qualsiasi file +TP_ICM_FILEDLGFILTERICM;Profili Colore +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. Da 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_PREFERREDPROFILE;Profilo DCP preferito +TP_ICM_PREFERREDPROFILE_1;Luce Diurna +TP_ICM_PREFERREDPROFILE_2;Tungsteno +TP_ICM_PREFERREDPROFILE_3;Fluorescente +TP_ICM_PREFERREDPROFILE_4;Flash +TP_ICM_SAVEREFERENCE;Salva riferimento per la profilazione +TP_ICM_TONECURVE;Usa la curva tono del DCP +TP_ICM_TONECURVE_TOOLTIP;Abilita per utilizzare le curve tono che possono essere contenute nei profili DCP. +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\ne applica la correzione Munsell +TP_LABCURVE_BRIGHTNESS;Luminosità +TP_LABCURVE_BWTONING;Viraggio B&W +TP_LABCURVE_BWTONING_TIP;Con l'opzione Viraggio B&W abilitata, la Cromaticità Lab e le curve CC, CH e LC non hanno effetto.\nIl Viraggio può essere ottenuto utilizzando le curve a e b. +TP_LABCURVE_CHROMATICITY;Cromaticità +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à C=f(C).\nIstogramma della Cromaticità prima delle reglazioni Curva.\nPer l'output finale fare riferimento al pannello Istogramma +TP_LABCURVE_CURVEEDITOR_CH;CH +TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Cromaticità secondo tonalità +TP_LABCURVE_CURVEEDITOR_LC;LC +TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminanza secondo cromaticità +TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminanza Lab L=f(L).\nIstogramma di L prima delle regolazioni Curva Lab.\nPer l'output finale fare riferimento al pannello Istogramma +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 (Luminanza a seconda dela cromaticità) è limitata 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;Riadatta +TP_LENSGEOM_LABEL;Obiettivo/Geometria +TP_LENSPROFILE_FILEDLGFILTERLCP;File di Correzione dell'Obiettivo +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_PERSPECTIVE_HORIZONTAL;Orizzontale +TP_PERSPECTIVE_LABEL;Prospettiva +TP_PERSPECTIVE_VERTICAL;Verticale +TP_PREPROCESS_GREENEQUIL;Bilanciamento del verde +TP_PREPROCESS_HOTDEADPIXFILT;Filtro pixel surriscaldati/guasti +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_BLACKONE;Punto del Nero: Rosso +TP_RAWEXPOS_BLACKS;Livelli del nero +TP_RAWEXPOS_BLACKTHREE;Punto del Nero: Verde 2 +TP_RAWEXPOS_BLACKTWO;Punto del Nero: Blu +TP_RAWEXPOS_BLACKZERO;Punto del Nero: Verde 1 (riferimento) +TP_RAWEXPOS_LINEAR;Punto del Bianco: fattore di comp. lineare +TP_RAWEXPOS_PRESER;Punto del Bianco: comp. (EV) di protezione alteluci +TP_RAWEXPOS_TWOGREEN;Valori del verde uniti +TP_RAW_ALLENHANCE;Limita rumore/artefatti dovuti alla demosaicizzazione +TP_RAW_DCBENHANCE;Passaggio di miglioramento per DCB +TP_RAW_DCBITERATIONS;Numero di iterazioni DCB +TP_RAW_DMETHOD;Metodo +TP_RAW_DMETHOD_PROGRESSBAR;Demosaicizzazione di %1... +TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Perfezionamento della demosaicizzazione... +TP_RAW_DMETHOD_TOOLTIP;Nota: IGV e LMMSE sono dedicati alle immagini ad alti ISO +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, 3, 4), poi aggiunge un perfezionamento (passi 5, 6) per ridurre gli artefatti e migliorare il rapporto segnale/rumore +TP_RESIZE_APPLIESTO;Applica a: +TP_RESIZE_BICUBICSF;Bicubico (più graduale) +TP_RESIZE_BICUBICSH;Bicubico (più definito) +TP_RESIZE_BICUBIC;Bicubico +TP_RESIZE_BILINEAR;Bilineare +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_SHADOWSHLIGHTS_HIGHLIGHTS;Alteluci +TP_SHADOWSHLIGHTS_HLTONALW;Gradualità delle Alteluci +TP_SHADOWSHLIGHTS_LABEL;Ombre/Alteluci +TP_SHADOWSHLIGHTS_LOCALCONTR;Contrasto Locale +TP_SHADOWSHLIGHTS_RADIUS;Raggio +TP_SHADOWSHLIGHTS_SHADOWS;Ombre +TP_SHADOWSHLIGHTS_SHTONALW;Gradualità 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 (Lab/CIECAM02) +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 (Lab/CIECAM02) +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 +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_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 manuale +TP_WBALANCE_TEMPERATURE;Temperatura +TP_WBALANCE_TUNGSTEN;Tungsteno +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. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!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_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_UNRANK_TOOLTIP;Unrank\nShortcut: Shift-0 +!HISTORY_MSG_205;CAM02 - Hot/bad pixels +!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;'CL' curve +!HISTORY_MSG_247;'LH' curve +!HISTORY_MSG_248;'HH' curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!PARTIALPASTE_CHANNELMIXERBW;Black-and-White +!PARTIALPASTE_GRADIENT;Graduated filter +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PREFERENCES_CUSTPROFBUILDKEYFORMAT;Keys format +!PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Name +!PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID +!PREFERENCES_USEBUNDLEDPROFILES;Use bundled profiles +!PROFILEPANEL_GLOBALPROFILES;Bundled profiles +!PROFILEPANEL_MYPROFILES;My profiles +!PROFILEPANEL_PINTERNAL;Neutral +!TP_BWMIX_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing channel-mixer +!TP_BWMIX_BLUE;Blue +!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;Modify luminance in function of hue\nPay attention to extreme values that may cause artifacts +!TP_BWMIX_CYAN;Cyan +!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 simulate shots taken with a colored filter placed in front of the lens. Colored filters reduce transmission of specific range of colors and correspondingly affect their lightness. E.g. a Red filter darkens Blue skies. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_BLUE;Blue Channel +!TP_BWMIX_GAM_GREEN;Green Channel +!TP_BWMIX_GAM_RED;Red Channel +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each channel RGB +!TP_BWMIX_GREEN;Green +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MAGENTA;Magenta +!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 (filter, channel-mixer) to default +!TP_BWMIX_ORANGE;Orange +!TP_BWMIX_PURPLE;Purple +!TP_BWMIX_RED;Red +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all of the mixer options\nTotal displays the sum of RGB values actually applied:\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 (films, landscape, ...) or manual settings of channel-mixer +!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;Channel-Mixer absolute RGB +!TP_BWMIX_SET_RGBREL;Channel-Mixer relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Channel-Mixer absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Channel-Mixer 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_BWMIX_YELLOW;Yellow +!TP_COLORAPP_ADAP_AUTO_TOOLTIP;If the checkbox is checked (recommended) RT 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.\n 0=no effect 1=median 2=gaussian.\n\nThese artifacts are due to limitations of CIECAM02. Alternatively, adjust the image to avoid very dark shadows. +!TP_DIRPYRDENOISE_ENH;Enhanced mode +!TP_DIRPYRDENOISE_ENH_TOOLTIP;Increases noise reduction quality at the expense of a 20% processing time increase +!TP_GENERAL_11SCALE_TOOLTIP;The effect of this tool or some of its sub-component is only visible at 1:1 preview scale. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Rotation anchor point X: -100=left edge, 0=center, +100=right edge +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Rotation anchor point Y: -100=top edge, 0=center, +100=bottom edge +!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 automatic exposure +!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_TOOLTIP;Save the linear TIFF image before the input profile is applied. Result can be used for calibration purposes, 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_PCVIGNETTE_FEATHER;Feather +!TP_PCVIGNETTE_FEATHER_TOOLTIP;Feathering: 0=corners only, 50=halfway to center, 100=to center +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness: 0=rectangle, 50=fitted ellipse, 100=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. Higher = more, lower = less. +!TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Try to suppress hot and dead pixels +!TP_SAVEDIALOG_OK_TIP;Shortcut Ctrl-Enter +!TP_SHADOWSHLIGHTS_SHARPMASK;Sharp mask +!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 diff --git a/rtdata/languages/Japanese b/rtdata/languages/Japanese new file mode 100644 index 000000000..c7c22e551 --- /dev/null +++ b/rtdata/languages/Japanese @@ -0,0 +1,1407 @@ +#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 + +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_FILEDLGFILTERANY;すべてのファイル +CURVEEDITOR_FILEDLGFILTERCURVE;カーブ・ファイル +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;タイプ: +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_COLORDENOISE;カラーノイズ低減を回避 +EXPORT_BYPASS_DEFRINGE;フリンジ低減を回避 +EXPORT_BYPASS_DIRPYRDENOISE;ノイズ低減を回避 +EXPORT_BYPASS_DIRPYREQUALIZER;ディテール・レベルのコントラストを回避 +EXPORT_BYPASS_LUMADENOISE;輝度ノイズ低減を回避 +EXPORT_BYPASS_RAW_ALL_ENHANCE;デモザイク後のアーティファクト/ノイズ低減を回避 +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;デモザイクの方式 +EXPORT_RESIZEMETHOD;リサイズの方式 +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;キャッシュをクリア - すべて +FILEBROWSER_CACHECLEARFROMPARTIAL;キャッシュをクリア - 一部 +FILEBROWSER_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_POPUPCOLORLABEL;カラー・ラベル +FILEBROWSER_POPUPCOPYTO;コピーします... +FILEBROWSER_POPUPFILEOPERATIONS;ファイルの操作 +FILEBROWSER_POPUPMOVEEND;キュー処理の最後に移動 +FILEBROWSER_POPUPMOVEHEAD;キュー処理の最初に移動 +FILEBROWSER_POPUPMOVETO;移動します... +FILEBROWSER_POPUPOPEN;開く +FILEBROWSER_POPUPPROCESSFAST;キューに追加 (高速書き出し) +FILEBROWSER_POPUPPROCESS;キューに追加 +FILEBROWSER_POPUPPROFILEOPERATIONS;プロファイルの操作 +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\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_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ショートカット: 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_USETEMPLATE;テンプレート使用: +FILEBROWSER_ZOOMINHINT;サムネイルサイズの拡大\nショートカット: +\n\nシングル・エディタ・タブのショートカット: Alt-+ +FILEBROWSER_ZOOMOUTHINT;サムネイルサイズの縮小\nショートカット: -\n\nシングル・エディタ・タブのショートカット: Alt-- +GENERAL_ABOUT;RawTherapeeについて.. +GENERAL_AFTER;補正後 +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;CIELAB 輝度・ヒストグラム 表示/非表示 +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;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;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;インパルス NR しきい値 +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;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;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;露光補正 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;'CC' カーブ +HISTORY_MSG_169;'CH' カーブ +HISTORY_MSG_170;自然な彩度 - カーブ +HISTORY_MSG_171;'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;‘CL’カーブ +HISTORY_MSG_247;"LH" カーブ +HISTORY_MSG_248;"HH" カーブ +HISTORY_MSG_249;ディテールコントラストのしきい値 +HISTORY_MSG_250;ノイズ低減 - 強化 +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_IPTC;IPTC +MAIN_TAB_METADATA;メタデータ +MAIN_TAB_METADATA_TOOLTIP;ショートカット: Alt-m +MAIN_TAB_RAW;RAW +MAIN_TAB_RAW_TOOLTIP;ショートカット: Alt-r +MAIN_TAB_TAGGING;タグ付け +MAIN_TAB_TRANSFORM;変形 +MAIN_TAB_TRANSFORM_TOOLTIP;ショートカット: Alt-t +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_NA;B = n/a +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_LAB_A_NA;a = n/a +NAVIGATOR_LAB_A_VALUE;a = %1 +NAVIGATOR_LAB_B_NA;b = n/a +NAVIGATOR_LAB_B_VALUE;b = %1 +NAVIGATOR_LAB_L_NA;L = n/a +NAVIGATOR_LAB_L_VALUE;L = %1 +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_V_VALUE;V = %1 +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_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_METAICMGROUP;メタデータ/ICM 設定 +PARTIALPASTE_PCVIGNETTE;ビネットフィルター +PARTIALPASTE_PERSPECTIVE;パースペクティブの補正 +PARTIALPASTE_PREPROCESS_GREENEQUIL;グリーン 平衡化 +PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;ホット/デッド ピクセル・フィルタを適用 +PARTIALPASTE_PREPROCESS_LINEDENOISE;ラインノイズ フィルタ +PARTIALPASTE_RAWCACORR_AUTO;自動色収差補正 +PARTIALPASTE_RAWCACORR_CABLUE;色収差 ブルー +PARTIALPASTE_RAWCACORR_CARED;色収差 レッド +PARTIALPASTE_RAWEXPOS_BLACK;黒レベル +PARTIALPASTE_RAWEXPOS_LINEAR;Raw 白ポイント リニア補正係数 +PARTIALPASTE_RAWEXPOS_PRESER;Raw 白ポイント HLを保持したまま補正 (EV) +PARTIALPASTE_RAWGROUP;Raw 設定 +PARTIALPASTE_RAW_ALLENHANCE;デモザイク後 アーティファクト/ノイズ低減を適用 +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_WHITEBALANCE;ホワイトバランス +PREFERENCES_ADD;追加 +PREFERENCES_APPLNEXTSTARTUP;要再起動 +PREFERENCES_AUTOMONPROFILE;OSのメインモニター・プロファイルを使用 +PREFERENCES_BATCH_PROCESSING;バッチ処理 +PREFERENCES_BEHADDALLHINT;すべてのパラメータを 追加モードにします\nバッチツールパネルのパラメータの調整は、格納されている値の差分になります +PREFERENCES_BEHADDALL;すべて '追加' +PREFERENCES_BEHAVIOR;ビヘイビア +PREFERENCES_BEHSETALLHINT;すべてのパラメータを 設定モードにします\nバッチツールパネルのパラメータの調整は絶対になり、実際の値が表示されます +PREFERENCES_BEHSETALL;すべて '設定' +PREFERENCES_BLACKBODY;タングステン +PREFERENCES_BLINKCLIPPED;クリッピング領域の点滅 +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.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_DATEFORMATFRAME;日付の形式 +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;RAWではない画像 +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_GTKTHEME;GTK デフォルト +PREFERENCES_HISTOGRAMPOSITIONLEFT;左パネルにヒストグラム +PREFERENCES_HLTHRESHOLD;ハイライト・クリッピング領域のしきい値 +PREFERENCES_ICCDIR;カラープロファイルを含むディレクトリ +PREFERENCES_IMPROCPARAMS;画像処理のデフォルト値 +PREFERENCES_INTENT_ABSOLUTE;絶対的な色域を維持 +PREFERENCES_INTENT_PERCEPTUAL;知覚的 +PREFERENCES_INTENT_RELATIVE;相対的な色域を維持 +PREFERENCES_INTENT_SATURATION;彩度 +PREFERENCES_INTERNALTHUMBIFUNTOUCHED;RAWファイルが未編集の場合 JPEGのサムネイルを表示 +PREFERENCES_LANGAUTODETECT;OSの言語設定を使用 +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\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_OVERWRITEOUTPUTFILE;既存ファイルを上書き +PREFERENCES_PANFACTORFRAME;パンの速度 +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;ノイズ低減は、10メガピクセル画像では128MB程度、40メガピクセル画像では512MBを必要とします、そして更にスレッドごとに128MBが必要です。複数のスレッドを同時に実行すると演算が速くなります。自動的にできる限り多くのスレッドを使用するには"0"の設定のままにします +PREFERENCES_SELECTFONT;フォント選択 +PREFERENCES_SELECTLANG;言語選択 +PREFERENCES_SELECTTHEME;テーマの選択 +PREFERENCES_SET;設定 +PREFERENCES_SHOWBASICEXIF;基本Exif情報を表示 +PREFERENCES_SHOWDATETIME;日付表示 +PREFERENCES_SHOWEXPOSURECOMPENSATION;露光補正追加 +PREFERENCES_SHOWPROFILESELECTOR;プロファイル・セレクタの表示 +PREFERENCES_SHTHRESHOLD;シャドウ・クリッピング領域のしきい値 +PREFERENCES_SINGLETABVERTAB;シングル編集タブモード, 垂直タブ +PREFERENCES_SINGLETAB;シングルタブモードモード +PREFERENCES_SLIMUI;スリムインタフェース +PREFERENCES_SND_BATCHQUEUEDONE;キュー処理 終了 +PREFERENCES_SND_HELP;ファイルパスを入力 または空欄(無音).\nWindowsはシステムサウンドの "SystemDefault", "SystemAsterisk"など..\nLinuxはシステムサウンドの "complete", "window-attention"などを使用します +PREFERENCES_SND_LNGEDITPROCDONE;編集処理 終了 +PREFERENCES_SND_TRESHOLDSECS;秒後 +PREFERENCES_SQUAREDETAILWINDOW;正方形のディテール・ウィンドウ(速い) +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;出力デバイスのホワイトバランス設定 (モニター, TV, プロジェクター,観視...) +PREFERENCES_WORKFLOW;レイアウト +PROFILEPANEL_COPYPPASTE;コピーするパラメータ +PROFILEPANEL_FILEDLGFILTERANY;すべてのファイル +PROFILEPANEL_FILEDLGFILTERPP;処理プロファイル +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_JPGFILTER;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_TIFFFILTER;TIFF ファイル +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_AUTOCH;オート +TP_BWMIX_AUTOCH_TIP;チャンネルミキサーの最適値を計算します +TP_BWMIX_BLUE;ブルー +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_CYAN;シアン +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_BLUE;ブルーチャンネル +TP_BWMIX_GAM_GREEN;グリーンチャンネル +TP_BWMIX_GAM_RED;レッドチャンネル +TP_BWMIX_GAM_TOOLTIP;RGB各チャンネルのガンマを修正 +TP_BWMIX_GREEN;グリーン +TP_BWMIX_LABEL;白黒 +TP_BWMIX_MAGENTA;マゼンタ +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_ORANGE;オレンジ +TP_BWMIX_PURPLE;パープル +TP_BWMIX_RED;レッド +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_BWMIX_YELLOW;イエロー +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の明るさは 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;CIECAM02調整前のL(Lab)のヒストグラムを表示\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調整前の色度(Lab)のヒストグラムを表示します\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調整前のLab値を表示します +TP_COLORAPP_DEGREE_AUTO_TOOLTIP;チェックボックスが有効の場合 (推奨)\nRTは、CAT02で使用され、更にCIECAM02全体で使用する最適値を算出します\n手動で値を設定するには、チェックボックスを無効にします (65以上の値を推奨) +TP_COLORAPP_DEGREE_TOOLTIP;CIE色順応変換2002(CAT02)の量 +TP_COLORAPP_GAMUT;色域制御 (Lab) +TP_COLORAPP_GAMUT_TOOLTIP;Labモードの色域制御を許可 +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の明度は Labや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;このオプションが無効になっている場合、トーンマッピングはLab空間を使用します\nこのオプションが有効になっている場合、トーンマッピングは、CIECAM02を使用します\nトーンマッピング(Lab/CIECAM02)ツールを有効にするには、この設定を有効にする必要があります +TP_COLORAPP_WBCAM;WB [RT+CAT02] + [出力] +TP_COLORAPP_WBRT;WB [RT] + [出力] +TP_CROP_FIXRATIO;縦横比固定 +TP_CROP_GTDIAGONALS;対角線 +TP_CROP_GTEPASSPORT;バイオメトリック・パスポート +TP_CROP_GTFRAME;フレーム +TP_CROP_GTGRID;グリッド +TP_CROP_GTHARMMEANS1;調和平均 1 +TP_CROP_GTHARMMEANS2;調和平均 2 +TP_CROP_GTHARMMEANS3;調和平均 3 +TP_CROP_GTHARMMEANS4;調和平均 4 +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;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と非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_PERF;RGB モード(RAW画像) +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, 一部のコンデジ, etc.) +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トーンマッピングモードは以下の設定を有効にします:\n 1. CIECAM02\n 2. アルゴリズム="明るさ + 鮮やかさ (QM)"\n 3. "CIECAM02 明るさ(Q)でトーンマッピング" +TP_EXPOSCORR_LABEL;Raw 白・黒・ポイント +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マニュアルの以下の項目を参照してください:\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軸: -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;CIELab ブレンディング +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_FILEDLGFILTERANY;すべてのファイル +TP_ICM_FILEDLGFILTERICM;カラープロファイル +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_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;Lab 明度カーブ +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;輝度に応じた輝度 Lab L=f(L) +TP_LABCURVE_LABEL;Lab 調整 +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_FILEDLGFILTERLCP;レンズ補正 ファイル +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_GREENEQUIL;グリーン 平衡化 +TP_PREPROCESS_HOTDEADPIXFILT;ホット/デッド ピクセル・フィルタ +TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;ホット/バッドピクセルの圧縮を試みます +TP_PREPROCESS_LABEL;前処理 +TP_PREPROCESS_LINEDENOISE;ラインノイズ フィルタ +TP_PREPROCESS_NO_FOUND;未検出 +TP_RAWCACORR_AUTO;自動補正 +TP_RAWCACORR_CABLUE;ブルー +TP_RAWCACORR_CARED;レッド +TP_RAWEXPOS_BLACKONE;黒レベル: レッド +TP_RAWEXPOS_BLACKS;黒レベル +TP_RAWEXPOS_BLACKTHREE;黒レベル: グリーン 2 +TP_RAWEXPOS_BLACKTWO;黒レベル: ブルー +TP_RAWEXPOS_BLACKZERO;黒レベル: グリーン 1 (主) +TP_RAWEXPOS_LINEAR;ホワイトポイント補正 +TP_RAWEXPOS_PRESER;ハイライトを保持 +TP_RAWEXPOS_TWOGREEN;2つのグリーンを連動 +TP_RAW_ALLENHANCE;デモザイク後 アーティファクト/ノイズ低減 +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;ガンマ追加 (step 1) - メディアン追加 (step 2,3,4), リファイン追加 (step 5,6) アーティファクトを低減しノイズ比を向上させます +TP_RESIZE_APPLIESTO;適用 : +TP_RESIZE_BICUBICSF;バイキュービック (ソフトに) +TP_RESIZE_BICUBICSH;バイキュービック (シャープに) +TP_RESIZE_BICUBIC;バイキュービック +TP_RESIZE_BILINEAR;バイリニア +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_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_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..0eada8776 --- /dev/null +++ b/rtdata/languages/Latvian @@ -0,0 +1,1441 @@ +#01 YYYY-MM-DD by nickname + +ADJUSTER_RESET_TO_DEFAULT;Atmest uz noklusēto +CURVEEDITOR_FILEDLGFILTERANY;Visi faili +CURVEEDITOR_FILEDLGFILTERCURVE;Līkņu faili +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 +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_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_SAVEAS;Kā... +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_TAGGING;Tagging +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_LUMACURVE;Spīduma līkne +PARTIALPASTE_METAICMGROUP;Metadati/ICM uzstādījumi +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_BLINKCLIPPED;Mirgot cirptos laukumus +PREFERENCES_CACHECLEARALL;Attīrīt visu +PREFERENCES_CACHECLEARPROFILES;Attīrīt Profilus +PREFERENCES_CACHECLEARTHUMBS;Attīrīt sīktēlus +PREFERENCES_CACHEFORMAT1;Savs (ātrāks un kvalitatīvāks) +PREFERENCES_CACHEFORMAT2;JPEG (mazāka diska vieta) +PREFERENCES_CACHEMAXENTRIES;Maksimālais keša ierakstu skaits +PREFERENCES_CACHEOPTS;Keša opcijas +PREFERENCES_CACHETHUMBFORM;Keša sīktēlu formāts +PREFERENCES_CACHETHUMBHEIGHT;Keša maksimālais sīktēla augstums +PREFERENCES_CLEARDLG_LINE1;Attīrīt kešu +PREFERENCES_CLEARDLG_LINE2;Tas var aizņemt dažas sekundes. +PREFERENCES_CLEARDLG_TITLE;Lūdzu uzgaidiet +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_GTKTHEME;GTK noklusētā +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_FILEDLGFILTERANY;Visus failus +PROFILEPANEL_FILEDLGFILTERPP;Apstrādes profili +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... +PROGRESSDLG_LOADING;Ielādēju failu... +PROGRESSDLG_PROCESSING;Apstrādāju attēlu... +PROGRESSDLG_SAVING;Saglabāju failu... +QINFO_ISO;ISO +QINFO_NOEXIF;Exif dati nav pieejami. +SAVEDLG_FILEFORMAT;Faila formāts +SAVEDLG_JPEGQUAL;JPEG Kvalitāte +SAVEDLG_JPGFILTER;JPEG faili +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 +SAVEDLG_TIFFFILTER;TIFF faili +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_DEGREE;grādi: +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_COLORBOOST_ACHANNEL;kanāls "a" +TP_COLORBOOST_AMOUNT;Apjoms +TP_COLORBOOST_AVOIDCOLORCLIP;Izvairīties no krāsu cirpšanas +TP_COLORBOOST_BCHANNEL;kanāls "b" +TP_COLORBOOST_CHANNEL;Kanāls +TP_COLORBOOST_CHSEPARATE;atsevišķi +TP_COLORBOOST_ENABLESATLIMITER;Ierobežot piesātinājumu +TP_COLORBOOST_LABEL;Krāsu pastiprināšana +TP_COLORBOOST_SATLIMIT;Piesātinājuma robeža +TP_COLORDENOISE_EDGESENSITIVE;Jutīgs uz malām +TP_COLORDENOISE_EDGETOLERANCE;Iecietība pret malām +TP_COLORDENOISE_LABEL;Krāsu trokšņu slāpēšana +TP_COLORDENOISE_RADIUS;Radius +TP_COLORSHIFT_BLUEYELLOW;Zils-Dzeltens +TP_COLORSHIFT_GREENMAGENTA;Zaļš-Fuksīns +TP_COLORSHIFT_LABEL;Krāsu nobīde +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;Attiecība: +TP_CROP_GTDIAGONALS;Diagonāles +TP_CROP_GTHARMMEANS1;Harmon. vidējais 1 +TP_CROP_GTHARMMEANS2;Harmon. vidējais 2 +TP_CROP_GTHARMMEANS3;Harmon. vidējais 3 +TP_CROP_GTHARMMEANS4;Harmon. vidējais 4 +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_FILEDLGFILTERANY;Visi faili +TP_ICM_FILEDLGFILTERICM;ICC Profilu faili +TP_ICM_GAMMABEFOREINPUT;Uzlikta Gammu pirms Ievades profila +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_LUMACURVE_BLACKLEVEL;Melnais +TP_LUMACURVE_BRIGHTNESS;Gaišums +TP_LUMACURVE_COMPRHIGHLIGHTS;Izgaismojumu spiešana +TP_LUMACURVE_COMPRSHADOWS;Ēnu spiešana +TP_LUMACURVE_CONTRAST;Kontrasts +TP_LUMACURVE_CURVEEDITOR;Spīduma līkne +TP_LUMACURVE_LABEL;Spīduma līkne +TP_RAW_DMETHOD;Metode +TP_RAW_FALSECOLOR;Neīsto krāsu slāpēšanas soļi +TP_RESIZE_BICUBICSF;Bikubiski (Mīkstāk) +TP_RESIZE_BICUBICSH;Bikubiski (Asāk) +TP_RESIZE_BICUBIC;Bikubiski +TP_RESIZE_BILINEAR;Bilineāri +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_AUTOCROP;Auto Kardēšana +TP_ROTATE_DEGREE;Grādi +TP_ROTATE_FILL;Aizpildīt +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_CURVES;Curves +!CURVEEDITOR_CURVE;Curve +!CURVEEDITOR_CUSTOM;Custom +!CURVEEDITOR_DARKS;Darks +!CURVEEDITOR_HIGHLIGHTS;Highlights +!CURVEEDITOR_LIGHTS;Lights +!CURVEEDITOR_MINMAXCPOINTS;Minima/Maxima control points +!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 +!EXIFFILTER_EXPOSURECOMPENSATION;Exposure Compensation (EV) +!EXIFFILTER_FILETYPE;File Type +!EXIFFILTER_METADATAFILTER;Enable Metadata Filters +!EXPORT_BYPASS_ALL;Select / Unselect All +!EXPORT_BYPASS_COLORDENOISE;Bypass Color denoise +!EXPORT_BYPASS_DEFRINGE;Bypass Defringe +!EXPORT_BYPASS_DIRPYRDENOISE;Bypass Noise Reduction +!EXPORT_BYPASS_DIRPYREQUALIZER;Bypass Contrast by Detail Levels +!EXPORT_BYPASS_LUMADENOISE;Bypass Luma denoise +!EXPORT_BYPASS_RAW_ALL_ENHANCE;Bypass Post Demosaic Artifact/Noise Reduction +!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 +!EXPORT_RESIZEMETHOD;Resize 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.\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\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_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_POPUPRANK;Rank +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!FILEBROWSER_QUERYHINT;Type a partial filename to search for or a comma-separated list.\nE.g. 1001,1004,1199 \n\nCtrl-F to focus to the Find text box.\nEnter to commence search.\nEsc to clear.\nShift-Esc to remove focus. +!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.\nShortcut: i\n\nShortcut in Single Editor Tab Mode: Alt-i +!FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show images recently saved.\nShortcut: Alt-7 +!FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show images not recently saved.\nShortcut: Alt-6 +!FILEBROWSER_SHOWUNCOLORHINT;Show images without Color label.\nShortcut: Alt-0 +!FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +!FILEBROWSER_UNRANK_TOOLTIP;Unrank\nShortcut: Shift-0 +!FILEBROWSER_USETEMPLATE;Use template: +!GENERAL_AFTER;After +!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\nClick right mouse button on image preview to freeze/unfreeze +!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram +!HISTOGRAM_TOOLTIP_FULL;Toggle full (on) or scaled (off) 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;Lab - Chromaticity +!HISTORY_MSG_96;'a' Curve +!HISTORY_MSG_97;'b' Curve +!HISTORY_MSG_98;Demosaicing Method +!HISTORY_MSG_99;Hot/Dead pixel filter +!HISTORY_MSG_100;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;Resizing applies to +!HISTORY_MSG_111;Lab - Avoid color shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;Lab - Protection +!HISTORY_MSG_114;DCB Iterations +!HISTORY_MSG_115;False Color Suppression +!HISTORY_MSG_116;DCB Enhancement +!HISTORY_MSG_117;Raw Red CA Correction +!HISTORY_MSG_118;Raw Blue CA Correction +!HISTORY_MSG_119;Line Noise Filter +!HISTORY_MSG_120;Green Equilibration +!HISTORY_MSG_121;Raw Auto CA +!HISTORY_MSG_122;Dark Frame Auto Select +!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 Select +!HISTORY_MSG_128;Flat Field Blur Radius +!HISTORY_MSG_129;Flat Field Blur Type +!HISTORY_MSG_130;Auto Distorion +!HISTORY_MSG_131;Noise Reduction Luma +!HISTORY_MSG_132;Noise Reduction 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;Edges Sharpening +!HISTORY_MSG_147;ES - Luminance Only +!HISTORY_MSG_148;Microcontrast +!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_150;Post Demosaic Artifact/Noise Reduction +!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;'CC' curve +!HISTORY_MSG_169;'CH' curve +!HISTORY_MSG_170;Vib - Curve +!HISTORY_MSG_171;'LC' curve +!HISTORY_MSG_172;Lab - 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 tones protection +!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 pixels +!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;'CL' curve +!HISTORY_MSG_247;'LH' curve +!HISTORY_MSG_248;'HH' curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +!MAIN_BUTTON_FULLSCREEN;Fullscreen +!MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the Next image relative to image open in Editor\nShortcut: Shift-F4\n\nTo navigate to the Next image relative to thumbnail selected in File Browser\nShortcut: F4 +!MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the Previous image relative to image open in Editor\nShortcut: Shift-F3 \n\nTo navigate to the Previous image relative to thumbnail selected in File Browser\nShortcut: F3 +!MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronize the File Browser with the Editor to reveal the thumbnail of the currently open image, and clear filters in File Browser \nShortcut: x\n\nAs above, but without clearing filters in File Browser\nShortcut: y\n(Note that thumbnail of the open file 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\ndoesn't exist. Please set a correct path in the Preference window. +!MAIN_MSG_SETPATHFIRST;You have to set a target path first in Preferences\nin order to use this function! +!MAIN_MSG_WRITEFAILED;Failed to write\n\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_METADATA_TOOLTIP;Shortcut: Alt-m +!MAIN_TAB_RAW;Raw +!MAIN_TAB_RAW_TOOLTIP;Shortcut: Alt-r +!MAIN_TAB_TRANSFORM_TOOLTIP;Shortcut: Alt-t +!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 10-30%\n\nPreview is rendered slower with Focus Mask turned on. +!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_NA;B = n/a +!NAVIGATOR_B_VALUE;B = %1 +!NAVIGATOR_G_NA;G = n/a +!NAVIGATOR_G_VALUE;G = %1 +!NAVIGATOR_H_NA;H = n/a +!NAVIGATOR_H_VALUE;H = %1 +!NAVIGATOR_LAB_A_NA;a = n/a +!NAVIGATOR_LAB_A_VALUE;a = %1 +!NAVIGATOR_LAB_B_NA;b = n/a +!NAVIGATOR_LAB_B_VALUE;b = %1 +!NAVIGATOR_LAB_L_NA;L = n/a +!NAVIGATOR_LAB_L_VALUE;L = %1 +!NAVIGATOR_R_NA;R = n/a +!NAVIGATOR_R_VALUE;R = %1 +!NAVIGATOR_S_NA;S = n/a +!NAVIGATOR_S_VALUE;S = %1 +!NAVIGATOR_V_NA;V = n/a +!NAVIGATOR_V_VALUE;V = %1 +!NAVIGATOR_XY_FULL;Width = %1, Height = %2 +!NAVIGATOR_XY_NA;x = n/a, y = n/a +!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;CIE Color Appearance Model 2002 +!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_EVERYTHING;Everything +!PARTIALPASTE_FLATFIELDAUTOSELECT;Flat field auto selection +!PARTIALPASTE_FLATFIELDBLURRADIUS;Flat field blur radius +!PARTIALPASTE_FLATFIELDBLURTYPE;Flat field blur type +!PARTIALPASTE_FLATFIELDFILE;Flat field file +!PARTIALPASTE_GRADIENT;Graduated filter +!PARTIALPASTE_HSVEQUALIZER;HSV equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!PARTIALPASTE_LABCURVE;Lab adjustments +!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_PERSPECTIVE;Perspective +!PARTIALPASTE_PREPROCESS_GREENEQUIL;Green equilibration +!PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Apply hot/dead 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_ALLENHANCE;Post-demosaic artifact/noise reduction +!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 +!PREFERENCES_ADD;Add +!PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!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_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_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 scipts 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_DATEFORMATFRAME;Date Format +!PREFERENCES_DIRDARKFRAMES;Dark frames directory +!PREFERENCES_EDITORLAYOUT;Editor Layout +!PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar (de-select for low resolution display) +!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_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;Output device's Yb luminance (%) +!PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogram in left panel +!PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Show embedded JPEG thumbnail if raw is unedited +!PREFERENCES_LANGAUTODETECT;Use OS language setting +!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_MULTITABDUALMON;Multiple Editor Tabs Mode (if available on second monitor) +!PREFERENCES_MULTITAB;Multiple Editor Tabs Mode +!PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails +!PREFERENCES_OVERWRITEOUTPUTFILE;Overwrite existing output files +!PREFERENCES_PANFACTORFRAME;Pan Rate Amplification +!PREFERENCES_PANFACTORLABEL;Factor +!PREFERENCES_PROPERTY;Property +!PREFERENCES_RGBDTL_LABEL;Max number of threads for Noise Reduction +!PREFERENCES_RGBDTL_TOOLTIP;Noise Reduction requires a baseline of about 128MB RAM for a 10MPix image or 512MB for a 40MPix image, and additionally 128MB RAM per thread. The more threads run in parallel, the faster the computation. Leave the setting at "0" to automatically use as many threads as possible. +!PREFERENCES_SELECTFONT;Select font +!PREFERENCES_SET;Set +!PREFERENCES_SHOWEXPOSURECOMPENSATION;Append exposure compensation +!PREFERENCES_SHOWPROFILESELECTOR;Show processing profile selector +!PREFERENCES_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs +!PREFERENCES_SINGLETAB;Single Editor Tab Mode +!PREFERENCES_SLIMUI;Slim interface +!PREFERENCES_SND_BATCHQUEUEDONE;Queue processing done +!PREFERENCES_SND_HELP;Either enter filepath or nothing (for no sound).\nOn Windows use "SystemDefault", "SystemAsterisk" etc. for system sounds.\nOn Linux use "complete", "window-attention" etc. for system sounds. +!PREFERENCES_SND_LNGEDITPROCDONE;Editor processing done +!PREFERENCES_SND_TRESHOLDSECS;after secs +!PREFERENCES_SQUAREDETAILWINDOW;Square detail window (faster) +!PREFERENCES_TAB_PERFORMANCE;Performance +!PREFERENCES_TAB_SOUND;Sounds +!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_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_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing channel-mixer +!TP_BWMIX_BLUE;Blue +!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;Modify luminance in function of hue\nPay attention to extreme values that may cause artifacts +!TP_BWMIX_CYAN;Cyan +!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 simulate shots taken with a colored filter placed in front of the lens. Colored filters reduce transmission of specific range of colors and correspondingly affect their lightness. E.g. a Red filter darkens Blue skies. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_BLUE;Blue Channel +!TP_BWMIX_GAM_GREEN;Green Channel +!TP_BWMIX_GAM_RED;Red Channel +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each channel RGB +!TP_BWMIX_GREEN;Green +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MAGENTA;Magenta +!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 (filter, channel-mixer) to default +!TP_BWMIX_ORANGE;Orange +!TP_BWMIX_PURPLE;Purple +!TP_BWMIX_RED;Red +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all of the mixer options\nTotal displays the sum of RGB values actually applied:\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 (films, landscape, ...) or manual settings of channel-mixer +!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;Channel-Mixer absolute RGB +!TP_BWMIX_SET_RGBREL;Channel-Mixer relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Channel-Mixer absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Channel-Mixer 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_BWMIX_YELLOW;Yellow +!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) RT 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.\n 0=no effect 1=median 2=gaussian.\n\nThese artifacts are due to limitations of CIECAM02. Alternatively, adjust the image to avoid very dark shadows. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from Lab and RGB brightness +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from Lab and RGB colorfulness +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from Lab and RGB saturation +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from Lab 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 Lab and RGB contrast +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from Lab and RGB contrast +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L (Lab) 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 (Lab) 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 Lab values before CIECAM02 adjustments +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RT 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 (Lab) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in Lab 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 Lab and RGB lightness +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model\n\nWB [RT] + [output]:\nRT's white balance is used for the scene, CIECAM02 is set to D50, the output device's white balance is set in Preferences > Color Management\n\nWB [RT+CAT02] + [output]:\nRT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences +!TP_COLORAPP_RSTPRO;Red & skin tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin tones protection (sliders and curves) +!TP_COLORAPP_SHARPCIE;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe with Q/C +!TP_COLORAPP_SHARPCIE_TOOLTIP;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe will use CIECAM02 if enabled. +!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;Change tones and colors to take into account the viewing conditions of the output device\n\nAverage:\nAverage light environment (standard)\nThe image will not change\n\nDim:\nDim environment (TV)\nThe image will become slighty dark\n\nDark:\nDark environment (projector)\nThe image will become more dark\n\nExtremly Dark:\nExtremly dark environment (cutsheet)\nThe image will become very dark +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if source 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 Lab 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_CROP_GTEPASSPORT;Biometric Passport +!TP_CROP_GTFRAME;Frame +!TP_CROP_GTGRID;Grid +!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_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_CHROMA;Chrominance - Master +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on gamma of the input color profile. Gamma of sRGB is assumed, thus if input image is in color profile of a different gamma, luminance noise reduction will vary. +!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_LAB;Lab +!TP_DIRPYRDENOISE_LDETAIL;Luminance Detail +!TP_DIRPYRDENOISE_LUMA;Luminance +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or Lab methods can be used.\n\nFor non-raw images Lab method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_PERF;RGB mode (raw images) +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGB;RGB +!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_THRESHOLD;Threshold +!TP_DISTORTION_AUTO;Auto Distortion Correction +!TP_DISTORTION_AUTO_TIP;(Exprimental) Correct lens distortion automatically for some cameras (Micro 4/3, some compact digital cameras, etc.) +!TP_EPD_EDGESTOPPING;Edge Stopping +!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 via Lab mode (standard) and CIECAM02 mode.\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_EXPOSCORR_LABEL;Raw White & Black Points +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggle execution of auto levels to automatically set parameter values based on image analysis\nEnable Highlight Reconstruction if necessary +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in auto level's 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 following section of the manual to learn how to achieve the best results with double curves:\nThe Toolbox > Exposure Tab > Exposure Panel > Tone Curve +!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_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!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_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 effect of this tool or some of its sub-component is only visible at 1:1 preview scale. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Rotation anchor point X: -100=left edge, 0=center, +100=right edge +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Rotation anchor point Y: -100=top edge, 0=center, +100=bottom edge +!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 automatic exposure +!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 blown 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 simple color matrix by dcraw, enhanced RawTherapee version (whichever is available based on camera model) or embedded in 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. Use only in special cases. +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. Result can be used for calibration purposes, 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;Lab 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;Can be used with the Chromaticity slider and the CC curve. +!TP_LENSGEOM_AUTOCROP;Auto Crop +!TP_LENSGEOM_FILL;Auto fill +!TP_LENSGEOM_LABEL;Lens / Geometry +!TP_LENSPROFILE_FILEDLGFILTERLCP;Lens correction files +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;CA Correction +!TP_LENSPROFILE_USEDIST;Distortion correction +!TP_LENSPROFILE_USEVIGN;Vignetting correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset 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: 0=corners only, 50=halfway to center, 100=to center +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness: 0=rectangle, 50=fitted ellipse, 100=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. Higher = more, lower = less. +!TP_PREPROCESS_GREENEQUIL;Green Equilibration +!TP_PREPROCESS_HOTDEADPIXFILT;Hot/Dead pixel filter +!TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Try to suppress hot and dead 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_BLACKONE;Black Level: Red +!TP_RAWEXPOS_BLACKS;Black Levels +!TP_RAWEXPOS_BLACKTHREE;Black Level: Green 2 +!TP_RAWEXPOS_BLACKTWO;Black Level: Blue +!TP_RAWEXPOS_BLACKZERO;Black Level: Green 1 (lead) +!TP_RAWEXPOS_LINEAR;White Point Correction +!TP_RAWEXPOS_PRESER;Highlight Preservation +!TP_RAWEXPOS_TWOGREEN;Link greens +!TP_RAW_ALLENHANCE;Post-Demosaic Artifact/Noise Reduction +!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 +!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_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 used 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_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_ZOOMFITSCREEN;Fit 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..d3f55e027 --- /dev/null +++ b/rtdata/languages/Magyar @@ -0,0 +1,1464 @@ +#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_FILEDLGFILTERANY;Minden állomány +CURVEEDITOR_FILEDLGFILTERCURVE;Görbék állományai +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: +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_COLORDENOISE;Színzajszűrés kihagyása +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_LUMADENOISE;Luminanciazaj-szűrés kihagyása +EXPORT_BYPASS_RAW_ALL_ENHANCE;Interpolálás utáni műtermék-/zajszűrés 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 +EXPORT_RESIZEMETHOD;Átméretezés 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_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_USETEMPLATE;Sablon használata: +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_SAVEAS;másként... +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_TAGGING;Címkézés +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_B_NA;B = n/a +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_LAB_A_NA;A = n/a +NAVIGATOR_LAB_A_VALUE;A = %1 +NAVIGATOR_LAB_B_NA;B = n/a +NAVIGATOR_LAB_B_VALUE;B = %1 +NAVIGATOR_LAB_L_NA;L = n/a +NAVIGATOR_LAB_L_VALUE;L = %1 +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_V_VALUE;V = %1 +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_LUMACURVE;Luminancia görbe +PARTIALPASTE_METAICMGROUP;Metaadat/Színprofil beállítások +PARTIALPASTE_PERSPECTIVE;Perspektíva +PARTIALPASTE_PREPROCESS_GREENEQUIL;Zöldegyensúly +PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Hot/dead pixel szűrő alkalmazása +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_ALLENHANCE;Interpoláció utáni műtermék-/zajszűrés +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_BLINKCLIPPED;Kiégett részek villogtatása +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_CACHEFORMAT1;Egyedi (gyorsabb és szebb) +PREFERENCES_CACHEFORMAT2;JPEG (kisebb a háttértáron) +PREFERENCES_CACHEMAXENTRIES;Gyorsítótárban tárolt képek max. száma +PREFERENCES_CACHEOPTS;Gyorsítótár beállítások +PREFERENCES_CACHETHUMBFORM;Előnézeti kép formátuma +PREFERENCES_CACHETHUMBHEIGHT;Előnézeti kép maximális magassága +PREFERENCES_CLEARDLG_LINE1;Gyorsítótár ürítése +PREFERENCES_CLEARDLG_LINE2;Ez eltarthat pár másodpercig. +PREFERENCES_CLEARDLG_TITLE;Kérem várjon +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_DATEFORMATFRAME;Dátum formátuma +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_GTKTHEME;Alap GTK kinézet +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_PANFACTORFRAME;Mozgatás gyorsításának mértéke +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_SHOWPROFILESELECTOR;Profilválasztó 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_SQUAREDETAILWINDOW;Négyzetes lupe (gyorsabb) +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_FILEDLGFILTERANY;Minden állomány +PROFILEPANEL_FILEDLGFILTERPP;Feldolgozási beállítások +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_LOADING;Fájl betöltése... +PROGRESSDLG_PROCESSING;Kép feldolgozása... +PROGRESSDLG_PROFILECHANGEDINBROWSER;A profil az állományböngészőben megváltozott +PROGRESSDLG_SAVING;Fájl mentése... +QINFO_ISO;ISO +QINFO_NOEXIF;EXIF adat nem áll rendelkezésre. +RBATCHQUEUE_AUTOSTART;Autoindítás +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_JPGFILTER;JPEG fájlok +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_TIFFFILTER;TIFF fájlok +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_DEGREE;fok: +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_COLORBOOST_ACHANNEL;"a" csatorna +TP_COLORBOOST_AMOUNT;Mérték +TP_COLORBOOST_AVOIDCOLORCLIP;Színcsatorna-telítődés elkerülése +TP_COLORBOOST_BCHANNEL;"b" csatorna +TP_COLORBOOST_CHANNEL;Csatorna +TP_COLORBOOST_CHSEPARATE;külön +TP_COLORBOOST_ENABLESATLIMITER;Telítettség korlátozás +TP_COLORBOOST_LABEL;Színtelítettség +TP_COLORBOOST_SATLIMIT;Telítettség korlát +TP_COLORDENOISE_EDGESENSITIVE;Élérzékeny +TP_COLORDENOISE_EDGETOLERANCE;Éltolerancia +TP_COLORDENOISE_LABEL;Színzaj-csökkentés +TP_COLORDENOISE_RADIUS;Sugár +TP_COLORSHIFT_BLUEYELLOW;Kék-Sárga +TP_COLORSHIFT_GREENMAGENTA;Zöld-Lila +TP_COLORSHIFT_LABEL;Színeltolás +TP_CROP_DPI;DPI= +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_GTHARMMEANS1;Aranymetszés 1 +TP_CROP_GTHARMMEANS2;Aranymetszés 2 +TP_CROP_GTHARMMEANS3;Aranymetszés 3 +TP_CROP_GTHARMMEANS4;Aranymetszés 4 +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_DETAIL_AMOUNT;Mérték +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_EQUALIZER_CONTRAST_MINUS;Kontraszt- +TP_EQUALIZER_CONTRAST_PLUS;Kontraszt+ +TP_EQUALIZER_FINEST;Finom részletek +TP_EQUALIZER_LABEL;Wavelet equalizer +TP_EQUALIZER_LARGEST;Durva részletek +TP_EQUALIZER_NEUTRAL;Semleges +TP_EXPOSCORR_LABEL;Raw fehér-fekete pont +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_EXPO_AFTER; Interpoláció után (RGB konverzió előtt) +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_HSVEQUALIZER1;Vörös +TP_HSVEQUALIZER2;Sárga +TP_HSVEQUALIZER3;Lime +TP_HSVEQUALIZER4;Zöld +TP_HSVEQUALIZER5;Aqua +TP_HSVEQUALIZER6;Kék +TP_HSVEQUALIZER7;Lila +TP_HSVEQUALIZER8;Magenta +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_FILEDLGFILTERANY;inden fájl +TP_ICM_FILEDLGFILTERICM;ICC színprofil fájl +TP_ICM_GAMMABEFOREINPUT;Gamma korrekció a bemeneti profil előtt +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_AVOIDCOLORCLIP;Színkiégés elkerülése +TP_LABCURVE_BRIGHTNESS;Világosság +TP_LABCURVE_CONTRAST;Kontraszt +TP_LABCURVE_CURVEEDITOR;Luminanciagörbe +TP_LABCURVE_ENABLESATLIMITER;Telítettségi küszöb engedélyezése +TP_LABCURVE_LABEL;Lab görbék +TP_LABCURVE_SATLIMIT;Telítettségi küszöb +TP_LABCURVE_SATURATION;Színtelítettség +TP_LENSGEOM_AUTOCROP;Automatikus vágás +TP_LENSGEOM_FILL;Automatikus kitöltés +TP_LENSGEOM_LABEL;Objektív / Geometria +TP_LUMACURVE_BLACKLEVEL;Fekete szint +TP_LUMACURVE_BRIGHTNESS;Fényerő +TP_LUMACURVE_COMPRHIGHLIGHTS;Világos tónusok tömörítése +TP_LUMACURVE_COMPRSHADOWS;Sötét tónusok tömörítése +TP_LUMACURVE_CONTRAST;Kontraszt +TP_LUMACURVE_CURVEEDITOR;Luminanciagörbe +TP_LUMACURVE_LABEL;Luminancia +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_HOTDEADPIXFILT;Hot/dead pixel szűrő alkalmazása +TP_PREPROCESS_HOTDEADPIXTHRESH;Hot/dead pixel érzékelés küszöbe +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_BLACKONE;Feketeszint: vörös +TP_RAWEXPOS_BLACKS;Feketeszintek +TP_RAWEXPOS_BLACKTHREE;Feketeszint: zöld 2 +TP_RAWEXPOS_BLACKTWO;Feketeszint: kék +TP_RAWEXPOS_BLACKZERO;Feketeszint: zöld 1 (vezető) +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_ALLENHANCE;Interpoláció utáni műtermék/zaj szűrése +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_BICUBICSF;Bicubic (lágyabb) +TP_RESIZE_BICUBICSH;Bicubic (keményebb) +TP_RESIZE_BICUBIC;Bicubic +TP_RESIZE_BILINEAR;Bilineáris +TP_RESIZE_CROPPEDAREA;Vágott terület +TP_RESIZE_DOWNSCALEB;Downscale (Jobb minőség) +TP_RESIZE_DOWNSCALEF;Downscale (Gyorsabb) +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_AUTOCROP;Automatikus kivágás +TP_ROTATE_DEGREE;Fok +TP_ROTATE_FILL;Kitöltés +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 +!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_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_UNRANK_TOOLTIP;Unrank\nShortcut: Shift-0 +!GENERAL_AUTO;Automatic +!GENERAL_CLOSE;Close +!GENERAL_WARNING;Warning +!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram +!HISTOGRAM_TOOLTIP_FULL;Toggle full (on) or scaled (off) histogram +!HISTORY_MSG_167;--unused-- +!HISTORY_MSG_168;'CC' curve +!HISTORY_MSG_169;'CH' curve +!HISTORY_MSG_170;Vib - Curve +!HISTORY_MSG_171;'LC' curve +!HISTORY_MSG_172;Lab - 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 tones protection +!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 pixels +!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;'CL' curve +!HISTORY_MSG_247;'LH' curve +!HISTORY_MSG_248;'HH' curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +!MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the Next image relative to image open in Editor\nShortcut: Shift-F4\n\nTo navigate to the Next image relative to thumbnail selected in File Browser\nShortcut: F4 +!MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the Previous image relative to image open in Editor\nShortcut: Shift-F3 \n\nTo navigate to the Previous image relative to thumbnail selected in File Browser\nShortcut: F3 +!MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronize the File Browser with the Editor to reveal the thumbnail of the currently open image, and clear filters in File Browser \nShortcut: x\n\nAs above, but without clearing filters in File Browser\nShortcut: y\n(Note that thumbnail of the open file 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\ndoesn't exist. Please set a correct path in the Preference window. +!MAIN_MSG_SETPATHFIRST;You have to set a target path first in Preferences\nin order to use this function! +!MAIN_MSG_WRITEFAILED;Failed to write\n\n"%1"\n\nMake sure that the folder exists and that you have write permission to it. +!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_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;CIE Color Appearance Model 2002 +!PARTIALPASTE_GRADIENT;Graduated filter +!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!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_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_CUSTPROFBUILDKEYFORMAT;Keys format +!PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Name +!PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID +!PREFERENCES_D50;5000K +!PREFERENCES_D55;5500K +!PREFERENCES_D60;6000K +!PREFERENCES_D65;6500K +!PREFERENCES_FLUOF2;Fluorescent F2 +!PREFERENCES_FLUOF7;Fluorescent F7 +!PREFERENCES_FLUOF11;Fluorescent F11 +!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;Output device's Yb luminance (%) +!PREFERENCES_MENUGROUPEXTPROGS;Group "Open with" +!PREFERENCES_RGBDTL_LABEL;Max number of threads for Noise Reduction +!PREFERENCES_RGBDTL_TOOLTIP;Noise Reduction requires a baseline of about 128MB RAM for a 10MPix image or 512MB for a 40MPix image, and additionally 128MB RAM per thread. The more threads run in parallel, the faster the computation. Leave the setting at "0" to automatically use as many threads as possible. +!PREFERENCES_TAB_PERFORMANCE;Performance +!PREFERENCES_USEBUNDLEDPROFILES;Use bundled profiles +!PREFERENCES_VIEW;Output device's white balance (monitor, TV, projector, viewing, etc.) +!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_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing channel-mixer +!TP_BWMIX_BLUE;Blue +!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;Modify luminance in function of hue\nPay attention to extreme values that may cause artifacts +!TP_BWMIX_CYAN;Cyan +!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 simulate shots taken with a colored filter placed in front of the lens. Colored filters reduce transmission of specific range of colors and correspondingly affect their lightness. E.g. a Red filter darkens Blue skies. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_BLUE;Blue Channel +!TP_BWMIX_GAM_GREEN;Green Channel +!TP_BWMIX_GAM_RED;Red Channel +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each channel RGB +!TP_BWMIX_GREEN;Green +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MAGENTA;Magenta +!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 (filter, channel-mixer) to default +!TP_BWMIX_ORANGE;Orange +!TP_BWMIX_PURPLE;Purple +!TP_BWMIX_RED;Red +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all of the mixer options\nTotal displays the sum of RGB values actually applied:\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 (films, landscape, ...) or manual settings of channel-mixer +!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;Channel-Mixer absolute RGB +!TP_BWMIX_SET_RGBREL;Channel-Mixer relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Channel-Mixer absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Channel-Mixer 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_BWMIX_YELLOW;Yellow +!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) RT 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.\n 0=no effect 1=median 2=gaussian.\n\nThese artifacts are due to limitations of CIECAM02. Alternatively, adjust the image to avoid very dark shadows. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from Lab and RGB brightness +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from Lab and RGB colorfulness +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from Lab and RGB saturation +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from Lab 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 Lab and RGB contrast +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from Lab and RGB contrast +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L (Lab) 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 (Lab) 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 Lab values before CIECAM02 adjustments +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RT 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 (Lab) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in Lab 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 Lab and RGB lightness +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model\n\nWB [RT] + [output]:\nRT's white balance is used for the scene, CIECAM02 is set to D50, the output device's white balance is set in Preferences > Color Management\n\nWB [RT+CAT02] + [output]:\nRT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences +!TP_COLORAPP_RSTPRO;Red & skin tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin tones protection (sliders and curves) +!TP_COLORAPP_SHARPCIE;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe with Q/C +!TP_COLORAPP_SHARPCIE_TOOLTIP;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe will use CIECAM02 if enabled. +!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;Change tones and colors to take into account the viewing conditions of the output device\n\nAverage:\nAverage light environment (standard)\nThe image will not change\n\nDim:\nDim environment (TV)\nThe image will become slighty dark\n\nDark:\nDark environment (projector)\nThe image will become more dark\n\nExtremly Dark:\nExtremly dark environment (cutsheet)\nThe image will become very dark +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if source 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 Lab 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_CROP_GTFRAME;Frame +!TP_DIRPYRDENOISE_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on gamma of the input color profile. Gamma of sRGB is assumed, thus if input image is in color profile of a different gamma, luminance noise reduction will vary. +!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_LDETAIL;Luminance Detail +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or Lab methods can be used.\n\nFor non-raw images Lab method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_PERF;RGB mode (raw images) +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGB;RGB +!TP_EPD_TOOLTIP;Tone mapping is possible via Lab mode (standard) and CIECAM02 mode.\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 following section of the manual to learn how to achieve the best results with double curves:\nThe Toolbox > Exposure Tab > Exposure Panel > Tone Curve +!TP_EXPOSURE_TCMODE_FILMLIKE;Film-like +!TP_EXPOSURE_TCMODE_LABEL1;Curve mode 1 +!TP_EXPOSURE_TCMODE_LABEL2;Curve mode 2 +!TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!TP_GENERAL_11SCALE_TOOLTIP;The effect of this tool or some of its sub-component is only visible at 1:1 preview scale. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Rotation anchor point X: -100=left edge, 0=center, +100=right edge +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Rotation anchor point Y: -100=top edge, 0=center, +100=bottom edge +!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 automatic exposure +!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_TOOLTIP;Save the linear TIFF image before the input profile is applied. Result can be used for calibration purposes, 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;Can be used with the Chromaticity slider and the CC curve. +!TP_LENSPROFILE_FILEDLGFILTERLCP;Lens correction files +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;CA Correction +!TP_LENSPROFILE_USEDIST;Distortion correction +!TP_LENSPROFILE_USEVIGN;Vignetting correction +!TP_PCVIGNETTE_FEATHER;Feather +!TP_PCVIGNETTE_FEATHER_TOOLTIP;Feathering: 0=corners only, 50=halfway to center, 100=to center +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness: 0=rectangle, 50=fitted ellipse, 100=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. Higher = more, lower = less. +!TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Try to suppress hot and dead pixels +!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 +!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_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 used 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_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 diff --git a/rtdata/languages/Nederlands b/rtdata/languages/Nederlands new file mode 100644 index 000000000..a28e4c822 --- /dev/null +++ b/rtdata/languages/Nederlands @@ -0,0 +1,1414 @@ +#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.1 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_FILEDLGFILTERANY;Alle bestanden +CURVEEDITOR_FILEDLGFILTERCURVE;Curvebestanden +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: +EDITWINDOW_TITLE;Bewerk afbeelding +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_COLORDENOISE;Kleurruisonderdrukking niet toepassen +EXPORT_BYPASS_DEFRINGE;Verzachten niet toepassen +EXPORT_BYPASS_DIRPYRDENOISE;Ruisonderdrukking niet toepassen +EXPORT_BYPASS_DIRPYREQUALIZER;Detailcontrast niet toepassen +EXPORT_BYPASS_LUMADENOISE;Ruisonderdrukking luminantiekanaal niet toepassen +EXPORT_BYPASS_RAW_ALL_ENHANCE;Demozaïek artefact/ruisonderdrukking niet toepassen [raw] +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 +EXPORT_RESIZEMETHOD;Grootte aanpassen: Methode +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\nSnelkoppelingen:\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 snelkoppeling:\nShift-Ctrl-0 No Color\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_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_POPUPOPEN;Open +FILEBROWSER_POPUPPROCESSFAST;Plaats in verwerkingsrij voor Snelle Export +FILEBROWSER_POPUPPROCESS;Plaats in verwerkingsrij +FILEBROWSER_POPUPPROFILEOPERATIONS;Profielbewerkingen +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;Typ een deel van de bestandsnaam \nCtrl-f Zet focus;\nEnter Zoeken +FILEBROWSER_QUERYLABEL; Zoeken: +FILEBROWSER_RANK1_TOOLTIP;Waardering 1 *\nSnelkoppeling: Shift-1 +FILEBROWSER_RANK2_TOOLTIP;Waardering 2 *\nSnelkoppeling: Shift-2 +FILEBROWSER_RANK3_TOOLTIP;Waardering 3 *\nSnelkoppeling: Shift-3 +FILEBROWSER_RANK4_TOOLTIP;Waardering 4 *\nSnelkoppeling: Shift-4 +FILEBROWSER_RANK5_TOOLTIP;Waardering 5 *\nSnelkoppeling: 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 Alt-1 +FILEBROWSER_SHOWCOLORLABEL2HINT;Toon foto's met label Geel Alt-2 +FILEBROWSER_SHOWCOLORLABEL3HINT;Toon foto's met label Groen Alt-3 +FILEBROWSER_SHOWCOLORLABEL4HINT;Toon foto's met label Blauw Alt-4 +FILEBROWSER_SHOWCOLORLABEL5HINT;Toon foto's met label Paars Alt-5 +FILEBROWSER_SHOWDIRHINT;Toon alle foto's in map +FILEBROWSER_SHOWEDITEDHINT;Toon bewerkte foto's 7 +FILEBROWSER_SHOWEDITEDNOTHINT;Toon niet-bewerkte foto's 6 +FILEBROWSER_SHOWEXIFINFO;Toon EXIF-info +FILEBROWSER_SHOWRANK1HINT;Toon foto's met 1 ster +FILEBROWSER_SHOWRANK2HINT;Toon foto's met 2 sterren +FILEBROWSER_SHOWRANK3HINT;Toon foto's met 3 sterren +FILEBROWSER_SHOWRANK4HINT;Toon foto's met 4 sterren +FILEBROWSER_SHOWRANK5HINT;Toon foto's met 5 sterren +FILEBROWSER_SHOWRECENTLYSAVEDHINT;Toon recent opgeslagen/verwerkte foto's Alt-7 +FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Toon niet-opgeslagen/verwerkte foto's Alt-6 +FILEBROWSER_SHOWTRASHHINT;Toon inhoud prullenbak +FILEBROWSER_SHOWUNCOLORHINT;Toon foto's zonder kleurlabel Alt-0 +FILEBROWSER_SHOWUNRANKHINT;Toon foto's zonder sterwaardering +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\nSnelkoppeling: Shift-0 +FILEBROWSER_USETEMPLATE;Gebruik sjabloon: +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;Compressie hoge lichten +HISTORY_MSG_10;Schaduwcompressie +HISTORY_MSG_11;Tooncurve 1 +HISTORY_MSG_12;Automatische belichting +HISTORY_MSG_13;Drempel +HISTORY_MSG_14;Lum: helderheid +HISTORY_MSG_15;Lum: contrast +HISTORY_MSG_16;Lum: schaduwen +HISTORY_MSG_17;Lum: compr. hoge lichten +HISTORY_MSG_18;Lum: schaduwcompressie +HISTORY_MSG_19;'L' Curve +HISTORY_MSG_20;Verscherpen +HISTORY_MSG_21;Verscherpen -Straal +HISTORY_MSG_22;Verscherpen -Hoeveelheid +HISTORY_MSG_23;Verscherpen -Drempel +HISTORY_MSG_24;Verscherp alleen randen +HISTORY_MSG_25;Verscherpen -Straal randverscherping +HISTORY_MSG_26;Verscherpen -Randtolerantie +HISTORY_MSG_27;Verscherpen -Halocontrole +HISTORY_MSG_28;Halocontrole -Hoeveelheid +HISTORY_MSG_29;Verscherpingsmethode +HISTORY_MSG_30;Straal RL-verscherping +HISTORY_MSG_31;Hoeveelheid RL-verscherping +HISTORY_MSG_32;Demping RL-verscherping +HISTORY_MSG_33;Herhaling RL-verscherping +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;Compressie hoge lichten +HISTORY_MSG_52;Schaduwen ophelderen +HISTORY_MSG_53;Toonomvang hoge lichten +HISTORY_MSG_54;Toonomvang schaduwen +HISTORY_MSG_55;Lokaal contrast +HISTORY_MSG_56;Straal schaduwen/hoge lichten +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;Afbeelding 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;Vignettering -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;Hoge kwaliteit schaduwen/hoge lichten +HISTORY_MSG_84;Perspectiefcorrectie +HISTORY_MSG_85;Lenscorrectie Profiel +HISTORY_MSG_86;RGB Curven - Luminositeit Mode +HISTORY_MSG_87;Spot-ruisonderdrukking +HISTORY_MSG_88;Spot-ruisond. -Drempel +HISTORY_MSG_89;Ruisonderdrukking +HISTORY_MSG_90;Ruis -Luminantie +HISTORY_MSG_91;Ruis -Chrominantie +HISTORY_MSG_92;Ruis -Gamma +HISTORY_MSG_93;Detailcontrast waarde +HISTORY_MSG_94;Detailcontrast +HISTORY_MSG_95;Chromaticiteit +HISTORY_MSG_96;'a'-curve +HISTORY_MSG_97;'b'-curve +HISTORY_MSG_98;Demozaïekproces +HISTORY_MSG_99;Fileter hete/dode pixels +HISTORY_MSG_100;RGB-verzadiging +HISTORY_MSG_101;HSV-balans -Tint +HISTORY_MSG_102;HSV-balans -Verzadiging +HISTORY_MSG_103;HSV-balans -Waarde +HISTORY_MSG_104;HSV-balans +HISTORY_MSG_105;Randverzachting +HISTORY_MSG_106;Randverzachting Straal +HISTORY_MSG_107;Randverzachting Srempel +HISTORY_MSG_108;Drempel compr. hoge lichten +HISTORY_MSG_109;Hoogte en breedte +HISTORY_MSG_110;Herschalen van: +HISTORY_MSG_111;Vermijd kleurverschuiving +HISTORY_MSG_112;--unused-- +HISTORY_MSG_113;Rode en huidtinten beschermen +HISTORY_MSG_114;DCB Herhalingen +HISTORY_MSG_115;Herhaling valse kleuren +HISTORY_MSG_116;Verbeterd DCB +HISTORY_MSG_117;CA-correctie Rood +HISTORY_MSG_118;CA-correctie Blauw +HISTORY_MSG_119;Lijnruis +HISTORY_MSG_120;Groenbalans drempel +HISTORY_MSG_121;Auto CA +HISTORY_MSG_122;Auto donkerframe +HISTORY_MSG_123;Donkerframe-opname +HISTORY_MSG_124;Lineaire bel.correctie +HISTORY_MSG_125;Bel.correctie behoud HL +HISTORY_MSG_126;Vlakveldopname +HISTORY_MSG_127;Vlakveld automatische selectie +HISTORY_MSG_128;Vlakveld verzachten straal +HISTORY_MSG_129;Vlakveld verzachten type +HISTORY_MSG_130;Automatische correctie lensvervorming +HISTORY_MSG_131;Ruisonderdrukking Luma +HISTORY_MSG_132;Ruisonderdrukking 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 combineer groenen +HISTORY_MSG_142;Randen - Herhalingen +HISTORY_MSG_143;Randen - Hoeveelheid +HISTORY_MSG_144;Microcontrast - Hoeveelheid +HISTORY_MSG_145;Microcontrast - Uniformiteit +HISTORY_MSG_146;Randen verscherpen +HISTORY_MSG_147;Verscherpen - alleen luminantie +HISTORY_MSG_148;Microcontrast +HISTORY_MSG_149;Microcontrast - 3x3 matrix +HISTORY_MSG_150;Nabewerking demozaïek +HISTORY_MSG_151;Levendigheid +HISTORY_MSG_152;Levendigheid - Pasteltinten +HISTORY_MSG_153;Levendigheid - Verzadigde tinten +HISTORY_MSG_154;Levendigheid - Bescherm huidtinten +HISTORY_MSG_155;Levendigheid - Vermijd kleurverschuiving +HISTORY_MSG_156;Levendigheid - Koppel pastel- en verzadigde tinten +HISTORY_MSG_157;Levendigheid - Drempel pastel/verzadiging +HISTORY_MSG_158;Sterkte +HISTORY_MSG_159;Randen +HISTORY_MSG_160;Schaal +HISTORY_MSG_161;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;--niet in gebruik-- +HISTORY_MSG_168;'Cc' curve +HISTORY_MSG_169;'Ch' curve +HISTORY_MSG_170;Levendigheid curve +HISTORY_MSG_171;'LC' curve +HISTORY_MSG_172;Beperk LC tot Rode en Huidtinten +HISTORY_MSG_173;Ruis - Luminantie Detail +HISTORY_MSG_174;CIECAM02 +HISTORY_MSG_175;CAM02 - Chrom. aanpassing hoeveelheid +HISTORY_MSG_176;CAM02 - Duistere Weergaveomstandigheden +HISTORY_MSG_177;CAM02 - Opnameomstandigheden Lum. Adaptatie +HISTORY_MSG_178;CAM02 - Weergaveomstandigheden Lum. Adaptatie +HISTORY_MSG_179;CAM02 - 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 - Donkere Weergaveomstandigheden +HISTORY_MSG_185;CAM02 - Gamut controle +HISTORY_MSG_186;CAM02 - Algoritme +HISTORY_MSG_187;CAM02 - Rode & Huidtinten beschermen +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 (hoek) +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 - Toon CIECAM in histogram +HISTORY_MSG_200;CAM02 - Tonemapping met Q +HISTORY_MSG_201;Ruis - Delta Chrominantie rood-groen +HISTORY_MSG_202;Ruis - Delta Chrominantie blauw-geel +HISTORY_MSG_203;Ruis - Methode +HISTORY_MSG_204;LMMSE Verbetering +HISTORY_MSG_205;CAM02 hete/dode pixels +HISTORY_MSG_206;CAT02 - Opnameomstandigheden auto +HISTORY_MSG_207;Verzachten Tint curve +HISTORY_MSG_208;Blauw/Rood Mixer +HISTORY_MSG_210;Grijsverloop Filter - Hoek +HISTORY_MSG_211;Grijsverloop Filter +HISTORY_MSG_212;Vignettering Filter - Sterkte +HISTORY_MSG_213;Vignettering Filter +HISTORY_MSG_214;Zwart-Wit +HISTORY_MSG_215;ZW Kanaalmixer Rood +HISTORY_MSG_216;ZW Kanaalmixer Groen +HISTORY_MSG_217;ZW Kanaalmixer Blauw +HISTORY_MSG_218;ZW Rood gamma +HISTORY_MSG_219;ZW Groen gamma +HISTORY_MSG_220;ZW Blauw gamma +HISTORY_MSG_221;ZW Kleur Filter +HISTORY_MSG_222;ZW Voorinstelling +HISTORY_MSG_223;ZW Kanaalmixer Oranje +HISTORY_MSG_224;ZW Kanaalmixer Geel +HISTORY_MSG_225;ZW Kanaalmixer Cyaan +HISTORY_MSG_226;ZW Kanaalmixer Magenta +HISTORY_MSG_227;ZW Kanaalmixer Paars +HISTORY_MSG_228;ZW Luminantie Mixer +HISTORY_MSG_229;ZW Luminantie Mixer +HISTORY_MSG_230;ZW Zwart-Wit mode +HISTORY_MSG_231;ZW Curve +HISTORY_MSG_232;ZW Curve Type +HISTORY_MSG_233;ZW Curve +HISTORY_MSG_234;ZW Curve Type +HISTORY_MSG_235;ZW Auto Kanaalmixer +HISTORY_MSG_236;ZW --niet in gebruik-- +HISTORY_MSG_237;ZW Mixer terugzetten +HISTORY_MSG_238;Grijsverloop - Straal +HISTORY_MSG_239;Grijsverloop - Sterkte +HISTORY_MSG_240;Grijsverloop - Centrum +HISTORY_MSG_241;Vignettering Filter - Straal +HISTORY_MSG_242;Vignettering Filter - Vorm +HISTORY_MSG_243;Vignettering - Straal +HISTORY_MSG_244;Vignettering - Sterkte +HISTORY_MSG_245;Vignettering - Centrum +HISTORY_MSG_246;'CL' curve +HISTORY_MSG_247;'LH' curve +HISTORY_MSG_248;'HH' curve +HISTORY_MSG_249;Detailcontrast - Drempel +HISTORY_MSG_250;Ruis -Verbeteren +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\nSnelkoppeling: Shift-F4\n\nNavigeer naar de volgende afbeelding relatief ten opzichte van de miniatuur geselecteerd in de Bestandsnavigator\nSnelkoppeling: 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\nSnelkoppeling: 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 \nSnelkoppeling: x\n\nAls voorgaand, maar zonder het verwijderen van de filters in de Bestandsnavigator \nSnelkoppeling: 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_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_TAGGING;Tags +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_NA;B = n/b +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_G_NA;G = n/b +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_H_NA;H = n/b +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_LAB_A_NA;A = n/b +NAVIGATOR_LAB_A_VALUE;A = %1 +NAVIGATOR_LAB_B_NA;B = n/b +NAVIGATOR_LAB_B_VALUE;B = %1 +NAVIGATOR_LAB_L_NA;L = n/b +NAVIGATOR_LAB_L_VALUE;L = %1 +NAVIGATOR_R_NA;R = n/b +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_S_NA;S = n/b +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_NA;V = n/b +NAVIGATOR_V_VALUE;V = %1 +NAVIGATOR_XY_FULL;Breedte = %1, Hoogte = %2 +NAVIGATOR_XY_NA;x = n/b, y = n/b +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_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_EVERYTHING;Alles +PARTIALPASTE_EXIFCHANGES;Wijzig Exif-gegevens +PARTIALPASTE_EXPOSURE;Belichting +PARTIALPASTE_FLATFIELDAUTOSELECT;Vlakveld autoselectie +PARTIALPASTE_FLATFIELDBLURRADIUS;Vlakveld verzachting straal +PARTIALPASTE_FLATFIELDBLURTYPE;Vlakveld verzachting type +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_METAICMGROUP;Metadata/ICM-instellingen +PARTIALPASTE_PCVIGNETTE;Vignettering Filter +PARTIALPASTE_PERSPECTIVE;Perspectief +PARTIALPASTE_PREPROCESS_GREENEQUIL;Groenbalans +PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Filter hete/dode pixels +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_ALLENHANCE;Nabewerking demozaïek artefact/ruisonderdrukking +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_AUTOMONPROFILE;Gebruik automatisch het standaard monitorprofiel \nvan het besturingsysteem +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_BLINKCLIPPED;Knipper bij over-/onderbelichting +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_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_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_DATEFORMATFRAME;Datumformaat +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_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_EXTERNALEDITOR;Externe editor +PREFERENCES_FBROWSEROPTS;Opties bestandsnavigator +PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Enkele rij navigator werkbalk (de-activeer voor lage resolutie) +PREFERENCES_FILEFORMAT;Bestandstype +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_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_GREY;Uitvoerapparaat's Yb luminantie (%) +PREFERENCES_GTKTHEME;GTK standaard +PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogram in linkerpaneel +PREFERENCES_HLTHRESHOLD;Grenswaarde overbelichting +PREFERENCES_ICCDIR;Map met ICC-profielen +PREFERENCES_IMPROCPARAMS;Standaardprofiel +PREFERENCES_INTENT_ABSOLUTE;Absolute colorimetrie +PREFERENCES_INTENT_PERCEPTUAL;Waargenomen colorimetrie +PREFERENCES_INTENT_RELATIVE;Relatieve colorimetrie +PREFERENCES_INTENT_SATURATION;Verzadiging +PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Toon interne RAW-miniatuur indien onbewerkt +PREFERENCES_LANGAUTODETECT;Gebruik taalinstellingen pc +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_MONITORICC;Monitorprofiel +PREFERENCES_MULTITABDUALMON;Multi-tab, indien beschikbaar op tweede monitor +PREFERENCES_MULTITAB;Multi-tab: elke foto opent in nieuw tabvenster +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_OVERWRITEOUTPUTFILE;Overschrijf bestaande output-bestanden +PREFERENCES_PANFACTORFRAME;Scroll-snelheid ingezoomd beeld +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_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 +PREFERENCES_RGBDTL_TOOLTIP;Ruisonderdrukking gebruikt 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_SHOWPROFILESELECTOR;Toon profielkiezer +PREFERENCES_SHTHRESHOLD;Grenswaarde onderbelichting +PREFERENCES_SINGLETABVERTAB;Enkel-tab ('filmstrip') modus met verticale tabs +PREFERENCES_SINGLETAB;Enkel-tab: foto's openen in zelfde tabvenster +PREFERENCES_SLIMUI;Slanke interface +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_SQUAREDETAILWINDOW;Vierkant detailvenster (sneller) +PREFERENCES_STARTUPIMDIR;Standaardmap bij opstarten +PREFERENCES_TAB_BROWSER;Bestandsnavigator +PREFERENCES_TAB_COLORMGR;Kleurbeheer +PREFERENCES_TAB_GENERAL;Algemeen +PREFERENCES_TAB_IMPROC;Beeldverwerking +PREFERENCES_TAB_PERFORMANCE;Prestaties +PREFERENCES_TAB_SOUND;Geluiden +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_WORKFLOW;Layout +PROFILEPANEL_COPYPPASTE;Te kopiëren parameters +PROFILEPANEL_FILEDLGFILTERANY;Alle bestanden +PROFILEPANEL_FILEDLGFILTERPP;Profielen +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 +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. +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_JPGFILTER;JPEG-bestanden +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_TIFFFILTER;TIFF-bestanden +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_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 rotatie is het geometrische midden van de afbeelding. +TOOLBAR_TOOLTIP_WB;Witbalans.\nSneltoets: w +TP_BWMIX_AUTOCH;Auto +TP_BWMIX_AUTOCH_TIP;Bereken optimale waardes voor de kanaalmixer. +TP_BWMIX_BLUE;Blauw +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_CYAN;Cyaan Filter +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_BLUE;Blauwe Kanaal +TP_BWMIX_GAM_GREEN;Groene Kanaal +TP_BWMIX_GAM_RED;Rode Kanaal +TP_BWMIX_GAM_TOOLTIP;Corrigeer gamma voor elk RGB kanaal +TP_BWMIX_GREEN;Groen +TP_BWMIX_LABEL;Zwart-Wit +TP_BWMIX_MAGENTA;Magenta Filter +TP_BWMIX_MET;Methode +TP_BWMIX_MET_CHANMIX;Kanaalmixer +TP_BWMIX_MET_DESAT;Desatureren +TP_BWMIX_MET_LUMEQUAL;Luminantie Balans +TP_BWMIX_MET_TOOLTIP;Keuze uit Desatureren - Luminantie Balans - Kanaalmixer. +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_ORANGE;Oranje Filter +TP_BWMIX_PURPLE;Paars Filter +TP_BWMIX_RED;Rood +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;Kanaalmixer absolute RGB +TP_BWMIX_SET_RGBREL;Kanaalmixer relatieve RGB +TP_BWMIX_SET_ROYGCBPMABS;Kanaalmixer absolute ROYGCBPM +TP_BWMIX_SET_ROYGCBPMREL;Kanaalmixer 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_BWMIX_YELLOW;Geel Filter +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;Linksom roteren.\nSneltoets: [ +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rechtsom roteren.\nSneltoets: ] +TP_COARSETRAF_TOOLTIP_VFLIP;Verticaal spiegelen +TP_COLORAPP_ADAPTSCENE;Adaptatie luminositeit (cd/m2) +TP_COLORAPP_ADAPTSCENE_TOOLTIP;Absolute luminantie van de opnameomgeving \n(gebruikelijk 2000cd/m2) +TP_COLORAPP_ADAPTVIEWING;Adaptatie luminositeit (cd/m2) +TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Absolute luminantie van de weergaveomgeving \n(gebruikelijk 16cd/m2) +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;Toont CIECAM02 uitvoer in het histogram van 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 helderheid (Q) +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_CROP_FIXRATIO;Verhouding: +TP_CROP_GTDIAGONALS;Diagonaalmethode +TP_CROP_GTEPASSPORT;Biometrisch paspoort +TP_CROP_GTFRAME;Frame +TP_CROP_GTGRID;Raster +TP_CROP_GTHARMMEANS1;Harmonische snede 1 +TP_CROP_GTHARMMEANS2;Harmonische snede 2 +TP_CROP_GTHARMMEANS3;Harmonische snede 3 +TP_CROP_GTHARMMEANS4;Harmonische snede 4 +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_BLUE;Delta Chrominantie Blauw & Geel +TP_DIRPYRDENOISE_CHROMA;Chrominantie +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_LDETAIL;Luminantie Detail +TP_DIRPYRDENOISE_LUMA;Luminantie +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_PERF;RGB mode (raw afbeeldingen) +TP_DIRPYRDENOISE_RED;Delta Chrominantie Rood & Groen +TP_DIRPYRDENOISE_RGB;RGB +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_THRESHOLD;Drempel +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_EXPOSCORR_LABEL;RAW Witpunt en Zwartniveau +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 Comprimeren Hoge lichten +TP_EXPOSURE_COMPRHIGHLIGHTS;Comprimeren Hoge lichten +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_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_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;Straal +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;Repareer hoge Lichten +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_FILEDLGFILTERANY;Alle bestanden +TP_ICM_FILEDLGFILTERICM;ICC-profielbestanden +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_PREFERREDPROFILE;Voorkeur DCP-Profiel +TP_ICM_PREFERREDPROFILE_1;Daglicht +TP_ICM_PREFERREDPROFILE_2;Gloeilamp +TP_ICM_PREFERREDPROFILE_3;TL +TP_ICM_PREFERREDPROFILE_4;Flits +TP_ICM_SAVEREFERENCE;Bewaar referentiefoto tbv. profiling +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, is de LC Curve (Luminantie volgens Chromaticiteit) beperkt tot 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_FILEDLGFILTERLCP;Lenscorrectie bestanden +TP_LENSPROFILE_LABEL;Lenscorrectie Profielen +TP_LENSPROFILE_USECA;Gebruik CA correctie +TP_LENSPROFILE_USEDIST;Gebruik lensvervorming correctie +TP_LENSPROFILE_USEVIGN;Gebruik 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_GREENEQUIL;Groenbalans +TP_PREPROCESS_HOTDEADPIXFILT;Filter hete/dode pixels +TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Probeer hete en dode pixels te onderdrukken. +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_BLACKONE;Zwartniveau: Rood +TP_RAWEXPOS_BLACKS;Zwartniveaus +TP_RAWEXPOS_BLACKTHREE;Zwartniveau: Groen 2 +TP_RAWEXPOS_BLACKTWO;Zwartniveau: Blauw +TP_RAWEXPOS_BLACKZERO;Zwartniveau: Groen 1 (leider) +TP_RAWEXPOS_LINEAR;Witpunt: Lineaire corr. factor +TP_RAWEXPOS_PRESER;Witpunt: Herstel hoge lichten (EV) +TP_RAWEXPOS_TWOGREEN;Koppel Groen 1 en 2 +TP_RAW_ALLENHANCE;Demozaïek artefact/ruisonderdrukking +TP_RAW_DCBENHANCE;Pas DCB-verbetering toe +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 +TP_RAW_LMMSE_TOOLTIP;Toevoegen gamma (stap 1) - Toevoegen mediaan (stap 2,3,4), vervolgens verfijnen (stap 5,6) om artefacten te verwijderen en de signaal/ruis ratio te verbeteren. +TP_RESIZE_APPLIESTO;Toepassen op: +TP_RESIZE_BICUBICSF;Bikubisch (zachter) +TP_RESIZE_BICUBICSH;Bikubisch (scherper) +TP_RESIZE_BICUBIC;Bikubisch +TP_RESIZE_BILINEAR;Bilineair +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_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_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 +TP_VIGNETTING_RADIUS;Straal +TP_VIGNETTING_STRENGTH;Sterkte +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: - + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!FILEBROWSER_POPUPRANK;Rank +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. Result can be used for calibration purposes, generation of a camera profile. +!TP_SAVEDIALOG_OK_TIP;Shortcut Ctrl-Enter +!TP_SHADOWSHLIGHTS_SHARPMASK;Sharp mask diff --git a/rtdata/languages/Norsk BM b/rtdata/languages/Norsk BM new file mode 100644 index 000000000..3fea08b98 --- /dev/null +++ b/rtdata/languages/Norsk BM @@ -0,0 +1,1440 @@ +#01 2009-02-12 Esben L. Kristensen + +ADJUSTER_RESET_TO_DEFAULT;Tilbake til standard +CURVEEDITOR_FILEDLGFILTERANY;Hvilken som helst fil +CURVEEDITOR_FILEDLGFILTERCURVE;Kurvefiler +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 +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_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_SAVEAS;Som... +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_TAGGING;Tagging +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_LUMACURVE;Luminanskurve +PARTIALPASTE_METAICMGROUP;Metadata/ICM innstillinger +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_BLINKCLIPPED;Vis merkede områder +PREFERENCES_CACHECLEARALL;Slett alle +PREFERENCES_CACHECLEARPROFILES;Slett profiler +PREFERENCES_CACHECLEARTHUMBS;Slett thumbnails +PREFERENCES_CACHEFORMAT1;Proprietært (Raskere og bedre kvalitet) +PREFERENCES_CACHEFORMAT2;JPEG (Mindre filstørrelse) +PREFERENCES_CACHEMAXENTRIES;Maksimalt antall cache oppføringer +PREFERENCES_CACHEOPTS;Cache innstillinger +PREFERENCES_CACHETHUMBFORM;Cache thumbnail format +PREFERENCES_CACHETHUMBHEIGHT;Maksimal Thumbnail Høyde +PREFERENCES_CLEARDLG_LINE1;Sletter cache +PREFERENCES_CLEARDLG_LINE2;Dette kan ta sin tid.. +PREFERENCES_CLEARDLG_TITLE;Vennligst vent +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_GTKTHEME;GTK standard +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_FILEDLGFILTERANY;Alle filer +PROFILEPANEL_FILEDLGFILTERPP;Bildebehandlingsprofiler +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... +PROGRESSDLG_LOADING;Laster fil... +PROGRESSDLG_PROCESSING;Prosesserer bilde... +PROGRESSDLG_SAVING;Lagrer fil... +QINFO_ISO;ISO +QINFO_NOEXIF;Exifdata utilgjengelig. +SAVEDLG_FILEFORMAT;Filformat +SAVEDLG_JPEGQUAL;JPEG-kvalitet +SAVEDLG_JPGFILTER;JPEG-filter +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 +SAVEDLG_TIFFFILTER;TIFF-filter +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_DEGREE;grad: +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_COLORBOOST_ACHANNEL;kanal "a" +TP_COLORBOOST_AMOUNT;Mengde +TP_COLORBOOST_AVOIDCOLORCLIP;Unngå fargeklipping +TP_COLORBOOST_BCHANNEL;kanal "b" +TP_COLORBOOST_CHANNEL;Kanal +TP_COLORBOOST_CHSEPARATE;separat +TP_COLORBOOST_ENABLESATLIMITER;Metningsgrense +TP_COLORBOOST_LABEL;Fargeforsterkning +TP_COLORBOOST_SATLIMIT;Metningsgrense +TP_COLORDENOISE_EDGESENSITIVE;Kantfølsomhet +TP_COLORDENOISE_EDGETOLERANCE;Kanttoleranse +TP_COLORDENOISE_LABEL;Farvestøyreduksjon +TP_COLORDENOISE_RADIUS;Radius +TP_COLORSHIFT_BLUEYELLOW;Blå-Gul +TP_COLORSHIFT_GREENMAGENTA;Grønn-Magenta +TP_COLORSHIFT_LABEL;Fargeskift +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;Fast proporsjon +TP_CROP_GTDIAGONALS;Diagonalreglen +TP_CROP_GTHARMMEANS1;Harmonisk metode 1 +TP_CROP_GTHARMMEANS2;Harmonisk metode 2 +TP_CROP_GTHARMMEANS3;Harmonisk metode 3 +TP_CROP_GTHARMMEANS4;Harmonisk metode 4 +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_FILEDLGFILTERANY;Alle filer +TP_ICM_FILEDLGFILTERICM;ICC profilfiler +TP_ICM_GAMMABEFOREINPUT;Profilen tilføyer Gamma +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_LUMACURVE_BLACKLEVEL;Sort +TP_LUMACURVE_BRIGHTNESS;Lysstyrke +TP_LUMACURVE_COMPRHIGHLIGHTS;Høylyskomprimering +TP_LUMACURVE_COMPRSHADOWS;Skyggekomprimering +TP_LUMACURVE_CONTRAST;Kontrast +TP_LUMACURVE_CURVEEDITOR;Luminanskurve +TP_LUMACURVE_LABEL;Luminanskurve +TP_RAW_DMETHOD;Metode +TP_RAW_FALSECOLOR;Falsk fargefortrengningsverdi +TP_RESIZE_BICUBICSF;Bikubisk (Bløtere) +TP_RESIZE_BICUBICSH;Bikubisk (Skarpere) +TP_RESIZE_BICUBIC;Bikubisk +TP_RESIZE_BILINEAR;Bilinjær +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_AUTOCROP;Autobeskjæring +TP_ROTATE_DEGREE;Antall grader +TP_ROTATE_FILL;Fyll +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_CURVES;Curves +!CURVEEDITOR_CURVE;Curve +!CURVEEDITOR_CUSTOM;Custom +!CURVEEDITOR_DARKS;Darks +!CURVEEDITOR_HIGHLIGHTS;Highlights +!CURVEEDITOR_LIGHTS;Lights +!CURVEEDITOR_MINMAXCPOINTS;Minima/Maxima control points +!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 +!EXIFFILTER_EXPOSURECOMPENSATION;Exposure Compensation (EV) +!EXIFFILTER_FILETYPE;File Type +!EXIFFILTER_METADATAFILTER;Enable Metadata Filters +!EXPORT_BYPASS_ALL;Select / Unselect All +!EXPORT_BYPASS_COLORDENOISE;Bypass Color denoise +!EXPORT_BYPASS_DEFRINGE;Bypass Defringe +!EXPORT_BYPASS_DIRPYRDENOISE;Bypass Noise Reduction +!EXPORT_BYPASS_DIRPYREQUALIZER;Bypass Contrast by Detail Levels +!EXPORT_BYPASS_LUMADENOISE;Bypass Luma denoise +!EXPORT_BYPASS_RAW_ALL_ENHANCE;Bypass Post Demosaic Artifact/Noise Reduction +!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 +!EXPORT_RESIZEMETHOD;Resize 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.\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\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_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_POPUPRANK;Rank +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!FILEBROWSER_QUERYHINT;Type a partial filename to search for or a comma-separated list.\nE.g. 1001,1004,1199 \n\nCtrl-F to focus to the Find text box.\nEnter to commence search.\nEsc to clear.\nShift-Esc to remove focus. +!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.\nShortcut: i\n\nShortcut in Single Editor Tab Mode: Alt-i +!FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show images recently saved.\nShortcut: Alt-7 +!FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show images not recently saved.\nShortcut: Alt-6 +!FILEBROWSER_SHOWUNCOLORHINT;Show images without Color label.\nShortcut: Alt-0 +!FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +!FILEBROWSER_UNRANK_TOOLTIP;Unrank\nShortcut: Shift-0 +!FILEBROWSER_USETEMPLATE;Use template: +!GENERAL_AFTER;After +!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\nClick right mouse button on image preview to freeze/unfreeze +!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram +!HISTOGRAM_TOOLTIP_FULL;Toggle full (on) or scaled (off) 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;Lab - Chromaticity +!HISTORY_MSG_96;'a' Curve +!HISTORY_MSG_97;'b' Curve +!HISTORY_MSG_98;Demosaicing Method +!HISTORY_MSG_99;Hot/Dead pixel filter +!HISTORY_MSG_100;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;Resizing applies to +!HISTORY_MSG_111;Lab - Avoid color shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;Lab - Protection +!HISTORY_MSG_114;DCB Iterations +!HISTORY_MSG_115;False Color Suppression +!HISTORY_MSG_116;DCB Enhancement +!HISTORY_MSG_117;Raw Red CA Correction +!HISTORY_MSG_118;Raw Blue CA Correction +!HISTORY_MSG_119;Line Noise Filter +!HISTORY_MSG_120;Green Equilibration +!HISTORY_MSG_121;Raw Auto CA +!HISTORY_MSG_122;Dark Frame Auto Select +!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 Select +!HISTORY_MSG_128;Flat Field Blur Radius +!HISTORY_MSG_129;Flat Field Blur Type +!HISTORY_MSG_130;Auto Distorion +!HISTORY_MSG_131;Noise Reduction Luma +!HISTORY_MSG_132;Noise Reduction 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;Edges Sharpening +!HISTORY_MSG_147;ES - Luminance Only +!HISTORY_MSG_148;Microcontrast +!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_150;Post Demosaic Artifact/Noise Reduction +!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;'CC' curve +!HISTORY_MSG_169;'CH' curve +!HISTORY_MSG_170;Vib - Curve +!HISTORY_MSG_171;'LC' curve +!HISTORY_MSG_172;Lab - 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 tones protection +!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 pixels +!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;'CL' curve +!HISTORY_MSG_247;'LH' curve +!HISTORY_MSG_248;'HH' curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +!MAIN_BUTTON_FULLSCREEN;Fullscreen +!MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the Next image relative to image open in Editor\nShortcut: Shift-F4\n\nTo navigate to the Next image relative to thumbnail selected in File Browser\nShortcut: F4 +!MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the Previous image relative to image open in Editor\nShortcut: Shift-F3 \n\nTo navigate to the Previous image relative to thumbnail selected in File Browser\nShortcut: F3 +!MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronize the File Browser with the Editor to reveal the thumbnail of the currently open image, and clear filters in File Browser \nShortcut: x\n\nAs above, but without clearing filters in File Browser\nShortcut: y\n(Note that thumbnail of the open file 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\ndoesn't exist. Please set a correct path in the Preference window. +!MAIN_MSG_SETPATHFIRST;You have to set a target path first in Preferences\nin order to use this function! +!MAIN_MSG_WRITEFAILED;Failed to write\n\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_METADATA_TOOLTIP;Shortcut: Alt-m +!MAIN_TAB_RAW;Raw +!MAIN_TAB_RAW_TOOLTIP;Shortcut: Alt-r +!MAIN_TAB_TRANSFORM_TOOLTIP;Shortcut: Alt-t +!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 10-30%\n\nPreview is rendered slower with Focus Mask turned on. +!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_NA;B = n/a +!NAVIGATOR_B_VALUE;B = %1 +!NAVIGATOR_G_NA;G = n/a +!NAVIGATOR_G_VALUE;G = %1 +!NAVIGATOR_H_NA;H = n/a +!NAVIGATOR_H_VALUE;H = %1 +!NAVIGATOR_LAB_A_NA;a = n/a +!NAVIGATOR_LAB_A_VALUE;a = %1 +!NAVIGATOR_LAB_B_NA;b = n/a +!NAVIGATOR_LAB_B_VALUE;b = %1 +!NAVIGATOR_LAB_L_NA;L = n/a +!NAVIGATOR_LAB_L_VALUE;L = %1 +!NAVIGATOR_R_NA;R = n/a +!NAVIGATOR_R_VALUE;R = %1 +!NAVIGATOR_S_NA;S = n/a +!NAVIGATOR_S_VALUE;S = %1 +!NAVIGATOR_V_NA;V = n/a +!NAVIGATOR_V_VALUE;V = %1 +!NAVIGATOR_XY_FULL;Width = %1, Height = %2 +!NAVIGATOR_XY_NA;x = n/a, y = n/a +!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;CIE Color Appearance Model 2002 +!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_EVERYTHING;Everything +!PARTIALPASTE_FLATFIELDAUTOSELECT;Flat field auto selection +!PARTIALPASTE_FLATFIELDBLURRADIUS;Flat field blur radius +!PARTIALPASTE_FLATFIELDBLURTYPE;Flat field blur type +!PARTIALPASTE_FLATFIELDFILE;Flat field file +!PARTIALPASTE_GRADIENT;Graduated filter +!PARTIALPASTE_HSVEQUALIZER;HSV equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!PARTIALPASTE_LABCURVE;Lab adjustments +!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_PERSPECTIVE;Perspective +!PARTIALPASTE_PREPROCESS_GREENEQUIL;Green equilibration +!PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Apply hot/dead 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_ALLENHANCE;Post-demosaic artifact/noise reduction +!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 +!PREFERENCES_ADD;Add +!PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!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_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_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 scipts 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_DATEFORMATFRAME;Date Format +!PREFERENCES_DIRDARKFRAMES;Dark frames directory +!PREFERENCES_EDITORLAYOUT;Editor Layout +!PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar (de-select for low resolution display) +!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_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;Output device's Yb luminance (%) +!PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogram in left panel +!PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Show embedded JPEG thumbnail if raw is unedited +!PREFERENCES_LANGAUTODETECT;Use OS language setting +!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_MULTITABDUALMON;Multiple Editor Tabs Mode (if available on second monitor) +!PREFERENCES_MULTITAB;Multiple Editor Tabs Mode +!PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails +!PREFERENCES_OVERWRITEOUTPUTFILE;Overwrite existing output files +!PREFERENCES_PANFACTORFRAME;Pan Rate Amplification +!PREFERENCES_PANFACTORLABEL;Factor +!PREFERENCES_PROPERTY;Property +!PREFERENCES_RGBDTL_LABEL;Max number of threads for Noise Reduction +!PREFERENCES_RGBDTL_TOOLTIP;Noise Reduction requires a baseline of about 128MB RAM for a 10MPix image or 512MB for a 40MPix image, and additionally 128MB RAM per thread. The more threads run in parallel, the faster the computation. Leave the setting at "0" to automatically use as many threads as possible. +!PREFERENCES_SELECTFONT;Select font +!PREFERENCES_SET;Set +!PREFERENCES_SHOWEXPOSURECOMPENSATION;Append exposure compensation +!PREFERENCES_SHOWPROFILESELECTOR;Show processing profile selector +!PREFERENCES_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs +!PREFERENCES_SINGLETAB;Single Editor Tab Mode +!PREFERENCES_SLIMUI;Slim interface +!PREFERENCES_SND_BATCHQUEUEDONE;Queue processing done +!PREFERENCES_SND_HELP;Either enter filepath or nothing (for no sound).\nOn Windows use "SystemDefault", "SystemAsterisk" etc. for system sounds.\nOn Linux use "complete", "window-attention" etc. for system sounds. +!PREFERENCES_SND_LNGEDITPROCDONE;Editor processing done +!PREFERENCES_SND_TRESHOLDSECS;after secs +!PREFERENCES_SQUAREDETAILWINDOW;Square detail window (faster) +!PREFERENCES_TAB_PERFORMANCE;Performance +!PREFERENCES_TAB_SOUND;Sounds +!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_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_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing channel-mixer +!TP_BWMIX_BLUE;Blue +!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;Modify luminance in function of hue\nPay attention to extreme values that may cause artifacts +!TP_BWMIX_CYAN;Cyan +!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 simulate shots taken with a colored filter placed in front of the lens. Colored filters reduce transmission of specific range of colors and correspondingly affect their lightness. E.g. a Red filter darkens Blue skies. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_BLUE;Blue Channel +!TP_BWMIX_GAM_GREEN;Green Channel +!TP_BWMIX_GAM_RED;Red Channel +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each channel RGB +!TP_BWMIX_GREEN;Green +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MAGENTA;Magenta +!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 (filter, channel-mixer) to default +!TP_BWMIX_ORANGE;Orange +!TP_BWMIX_PURPLE;Purple +!TP_BWMIX_RED;Red +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all of the mixer options\nTotal displays the sum of RGB values actually applied:\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 (films, landscape, ...) or manual settings of channel-mixer +!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;Channel-Mixer absolute RGB +!TP_BWMIX_SET_RGBREL;Channel-Mixer relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Channel-Mixer absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Channel-Mixer 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_BWMIX_YELLOW;Yellow +!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) RT 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.\n 0=no effect 1=median 2=gaussian.\n\nThese artifacts are due to limitations of CIECAM02. Alternatively, adjust the image to avoid very dark shadows. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from Lab and RGB brightness +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from Lab and RGB colorfulness +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from Lab and RGB saturation +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from Lab 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 Lab and RGB contrast +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from Lab and RGB contrast +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L (Lab) 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 (Lab) 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 Lab values before CIECAM02 adjustments +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RT 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 (Lab) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in Lab 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 Lab and RGB lightness +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model\n\nWB [RT] + [output]:\nRT's white balance is used for the scene, CIECAM02 is set to D50, the output device's white balance is set in Preferences > Color Management\n\nWB [RT+CAT02] + [output]:\nRT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences +!TP_COLORAPP_RSTPRO;Red & skin tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin tones protection (sliders and curves) +!TP_COLORAPP_SHARPCIE;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe with Q/C +!TP_COLORAPP_SHARPCIE_TOOLTIP;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe will use CIECAM02 if enabled. +!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;Change tones and colors to take into account the viewing conditions of the output device\n\nAverage:\nAverage light environment (standard)\nThe image will not change\n\nDim:\nDim environment (TV)\nThe image will become slighty dark\n\nDark:\nDark environment (projector)\nThe image will become more dark\n\nExtremly Dark:\nExtremly dark environment (cutsheet)\nThe image will become very dark +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if source 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 Lab 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_CROP_GTEPASSPORT;Biometric Passport +!TP_CROP_GTFRAME;Frame +!TP_CROP_GTGRID;Grid +!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_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_CHROMA;Chrominance - Master +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on gamma of the input color profile. Gamma of sRGB is assumed, thus if input image is in color profile of a different gamma, luminance noise reduction will vary. +!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_LAB;Lab +!TP_DIRPYRDENOISE_LDETAIL;Luminance Detail +!TP_DIRPYRDENOISE_LUMA;Luminance +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or Lab methods can be used.\n\nFor non-raw images Lab method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_PERF;RGB mode (raw images) +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGB;RGB +!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_THRESHOLD;Threshold +!TP_DISTORTION_AUTO;Auto Distortion Correction +!TP_DISTORTION_AUTO_TIP;(Exprimental) Correct lens distortion automatically for some cameras (Micro 4/3, some compact digital cameras, etc.) +!TP_EPD_EDGESTOPPING;Edge Stopping +!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 via Lab mode (standard) and CIECAM02 mode.\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_EXPOSCORR_LABEL;Raw White & Black Points +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggle execution of auto levels to automatically set parameter values based on image analysis\nEnable Highlight Reconstruction if necessary +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in auto level's 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 following section of the manual to learn how to achieve the best results with double curves:\nThe Toolbox > Exposure Tab > Exposure Panel > Tone Curve +!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_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!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_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 effect of this tool or some of its sub-component is only visible at 1:1 preview scale. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Rotation anchor point X: -100=left edge, 0=center, +100=right edge +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Rotation anchor point Y: -100=top edge, 0=center, +100=bottom edge +!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 automatic exposure +!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 blown 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 simple color matrix by dcraw, enhanced RawTherapee version (whichever is available based on camera model) or embedded in 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. Use only in special cases. +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. Result can be used for calibration purposes, 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;Lab 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;Can be used with the Chromaticity slider and the CC curve. +!TP_LENSGEOM_AUTOCROP;Auto Crop +!TP_LENSGEOM_FILL;Auto fill +!TP_LENSGEOM_LABEL;Lens / Geometry +!TP_LENSPROFILE_FILEDLGFILTERLCP;Lens correction files +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;CA Correction +!TP_LENSPROFILE_USEDIST;Distortion correction +!TP_LENSPROFILE_USEVIGN;Vignetting correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset 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: 0=corners only, 50=halfway to center, 100=to center +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness: 0=rectangle, 50=fitted ellipse, 100=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. Higher = more, lower = less. +!TP_PREPROCESS_GREENEQUIL;Green Equilibration +!TP_PREPROCESS_HOTDEADPIXFILT;Hot/Dead pixel filter +!TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Try to suppress hot and dead 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_BLACKONE;Black Level: Red +!TP_RAWEXPOS_BLACKS;Black Levels +!TP_RAWEXPOS_BLACKTHREE;Black Level: Green 2 +!TP_RAWEXPOS_BLACKTWO;Black Level: Blue +!TP_RAWEXPOS_BLACKZERO;Black Level: Green 1 (lead) +!TP_RAWEXPOS_LINEAR;White Point Correction +!TP_RAWEXPOS_PRESER;Highlight Preservation +!TP_RAWEXPOS_TWOGREEN;Link greens +!TP_RAW_ALLENHANCE;Post-Demosaic Artifact/Noise Reduction +!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 +!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_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 used 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_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_ZOOMFITSCREEN;Fit 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..bda89aa42 --- /dev/null +++ b/rtdata/languages/Polish @@ -0,0 +1,1476 @@ +#01 2007-12-24 Mateusz Ludwin +#02 2010-01-08 Initial update for 3.0 release by 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 + +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;Cienie +CURVEEDITOR_FILEDLGFILTERANY;Wszystkie pliki +CURVEEDITOR_FILEDLGFILTERCURVE;Pliki z krzywymi +CURVEEDITOR_HIGHLIGHTS;Światła +CURVEEDITOR_LIGHTS;Światła +CURVEEDITOR_LINEAR;Liniowa +CURVEEDITOR_LOADDLGLABEL;Wczytaj krzywą... +CURVEEDITOR_MINMAXCPOINTS;Min/Max punktów kontrolnych +CURVEEDITOR_NURBS;Kontrolowana +CURVEEDITOR_PARAMETRIC;Parametryczna +CURVEEDITOR_SAVEDLGLABEL;Zapisz krzywą... +CURVEEDITOR_SHADOWS;Cienie +CURVEEDITOR_TOOLTIPCOPY;Skopiuj aktualną krzywą do schowka +CURVEEDITOR_TOOLTIPLINEAR;Zresetuj krzywą do liniowej +CURVEEDITOR_TOOLTIPLOAD;Wczytaj krzywą z pliku +CURVEEDITOR_TOOLTIPPASTE;Wstaw krzywą ze schowka +CURVEEDITOR_TOOLTIPSAVE;Zapisz aktualną krzywą +CURVEEDITOR_TYPE;Typ: +EDITWINDOW_TITLE;Edytuj obraz +EXIFFILTER_APERTURE;Przysłona +EXIFFILTER_CAMERA;Aparat +EXIFFILTER_EXPOSURECOMPENSATION;Korekta Ekspozycji (EV) +EXIFFILTER_FILETYPE;Typ pliku +EXIFFILTER_FOCALLEN;Wartość ogniskowej +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Obiektyw +EXIFFILTER_METADATAFILTER;Filtr 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_COLORDENOISE;Pomiń odszumienie koloru +EXPORT_BYPASS_DEFRINGE;Pomiń usuwanie widma +EXPORT_BYPASS_DIRPYRDENOISE;Pomiń redukcje szumu +EXPORT_BYPASS_DIRPYREQUALIZER;Pomiń kontrast wg. poziomu detali +EXPORT_BYPASS_LUMADENOISE;Pomiń odszumianie luminancji +EXPORT_BYPASS_RAW_ALL_ENHANCE;Pomiń redukcję szumu i artefaktów po demozaikowaniu +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/świateł +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 +EXPORT_RESIZEMETHOD;Metoda zmiany rozmiaru +EXTPROGTARGET_1;raw +EXTPROGTARGET_2;wywołane w kolejce +FILEBROWSER_ADDDELTEMPLATE;Dodaj/Usuń szablon... +FILEBROWSER_APPLYPROFILE;Zastosuj profil +FILEBROWSER_APPLYPROFILE_PARTIAL;Zastosuj profil (częściowo) +FILEBROWSER_AUTODARKFRAME;Automatyczne użycie czarnej klatki +FILEBROWSER_AUTOFLATFIELD;Automatyczne użycie klatki z pustym polem +FILEBROWSER_BROWSEPATHBUTTONHINT;Proszę kliknąć, by 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 pliki? +FILEBROWSER_EMPTYTRASHHINT;Definitywnie usuwa pliki z kosza +FILEBROWSER_EMPTYTRASH;Wyczyść kosz +FILEBROWSER_EXEC_CPB;Uruchom zewnętrzny kreator profilu dla zdjęcia +FILEBROWSER_EXTPROGMENU;Otwórz za pomocą +FILEBROWSER_FLATFIELD;Puste pole +FILEBROWSER_MOVETODARKFDIR;Przenieś do katalogu z czarnymi klatkami +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_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_POPUPOPEN;Otwórz +FILEBROWSER_POPUPPROCESSFAST;Dodaj do kolejki szybkiego eksportu +FILEBROWSER_POPUPPROCESS;Umieść w kolejce do przetwarzania +FILEBROWSER_POPUPPROFILEOPERATIONS;Profile +FILEBROWSER_POPUPREMOVEINCLPROC;Usuń z dysku i wyników przetwarzania +FILEBROWSER_POPUPREMOVE;Usuń z systemu plików +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ść okno opcji szukaj +FILEBROWSER_QUERYHINT;Proszę wprowadzić część nazwy, bo zlokalizować plik \nCtrl-f zaznaczenie\nEnter uruchamia wyszukiwanie +FILEBROWSER_QUERYLABEL; Znajdź: +FILEBROWSER_RANK1_TOOLTIP;Ocena 1 *\nSkrót: Shift-1 +FILEBROWSER_RANK2_TOOLTIP;Ocena 2 *\nSkrót: Shift-2 +FILEBROWSER_RANK3_TOOLTIP;Ocena 3 *\nSkrót: Shift-3 +FILEBROWSER_RANK4_TOOLTIP;Ocena 4 *\nSkrót: Shift-4 +FILEBROWSER_RANK5_TOOLTIP;Ocena 5 *\nSkrót: Shift-5 +FILEBROWSER_RENAMEDLGLABEL;Zmień nazwę pliku +FILEBROWSER_RENAMEDLGMSG;Zmień nazwę plki "%1" na: +FILEBROWSER_SELECTDARKFRAME;Wybierz czarną klatkę... +FILEBROWSER_SELECTFLATFIELD;Wybierz puste pole... +FILEBROWSER_SHOWCOLORLABEL1HINT;Pokazuje zdjęcia z czerwoną etykietą Alt-1 +FILEBROWSER_SHOWCOLORLABEL2HINT;Pokazuje zdjęcia z żółtą etykietą Alt-2 +FILEBROWSER_SHOWCOLORLABEL3HINT;Pokazuje zdjęcia z zieloną etykietą Alt-3 +FILEBROWSER_SHOWCOLORLABEL4HINT;Pokazuje zdjęcia z niebieską etykietą Alt-4 +FILEBROWSER_SHOWCOLORLABEL5HINT;Pokazuje zdjęcia z purpurową etykietą Alt-5 +FILEBROWSER_SHOWDIRHINT;Pokazuje wszystkie zdjęcia w katalogu +FILEBROWSER_SHOWEDITEDHINT;Pokazuje edytowane zdjęcia 7 +FILEBROWSER_SHOWEDITEDNOTHINT;Pokazuje nieedytowane zdjęcia 6 +FILEBROWSER_SHOWEXIFINFO;Pokaż dane EXIF i +FILEBROWSER_SHOWRANK1HINT;Pokazuje zdjęcia ocenione na 1 gwiazdkę +FILEBROWSER_SHOWRANK2HINT;Pokazuje zdjęcia ocenione na 2 gwiazdki +FILEBROWSER_SHOWRANK3HINT;Pokazuje zdjęcia ocenione na 3 gwiazdki +FILEBROWSER_SHOWRANK4HINT;Pokazuje zdjęcia ocenione na 4 gwiazdki +FILEBROWSER_SHOWRANK5HINT;Pokazuje zdjęcia ocenione na 5 gwiazdek +FILEBROWSER_SHOWRECENTLYSAVEDHINT;Pokazuje ostatnio zapisane zdjęcia Alt-7 +FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Pokazuje niezapisywane ostatnio zdjęcia Alt-6 +FILEBROWSER_SHOWTRASHHINT;Pokazuje zawartość kosza +FILEBROWSER_SHOWUNCOLORHINT;Pokazuje zdjęcia bez kolorowej etykiety Alt-0 +FILEBROWSER_SHOWUNRANKHINT;Pokazuje nieocenione zdjęcia +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_USETEMPLATE;Użyj szablonu: +FILEBROWSER_ZOOMINHINT;Zwiększa rozmiar miniaturek +FILEBROWSER_ZOOMOUTHINT;Zmniejsza rozmiar miniaturek +GENERAL_ABOUT;O programie +GENERAL_AFTER;Przed +GENERAL_AUTO;Automatyczne +GENERAL_BEFORE;Po +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/skalowany +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;Dowolna krzywa +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;Jasność +HISTORY_MSG_6;Kontrast +HISTORY_MSG_7;Czerń +HISTORY_MSG_8;Kompensacja ekspozycji +HISTORY_MSG_9;Kompresja świateł +HISTORY_MSG_10;Kompresja cieni +HISTORY_MSG_11;Krzywa tonalna +HISTORY_MSG_12;Automatyczna ekspozycja +HISTORY_MSG_13;Przycinanie ekspozycji +HISTORY_MSG_14;Jasność luminancji +HISTORY_MSG_15;Kontrast luminancji +HISTORY_MSG_16;Czerń luminancji +HISTORY_MSG_17;Kompr. świateł luminancji +HISTORY_MSG_18;Kompr. cieni luminancji +HISTORY_MSG_19;Krzywa luminancji +HISTORY_MSG_20;Wyostrzanie +HISTORY_MSG_21;Promień wyostrzania +HISTORY_MSG_22;Siła wyostrzania +HISTORY_MSG_23;Próg wyostrzania +HISTORY_MSG_24;Wyostrz tylko krawędzie +HISTORY_MSG_25;Promień detekcji krawędzi wyostrzania +HISTORY_MSG_26;Tolerancja wyostrzania krawędzi +HISTORY_MSG_27;Kontrola poświaty wyostrzania +HISTORY_MSG_28;Stopień kontroli poświaty +HISTORY_MSG_29;Metoda wyostrzania +HISTORY_MSG_30;Promień dekonwolucji +HISTORY_MSG_31;Siła dekonwolucji +HISTORY_MSG_32;Tłumienie dekonwolucji +HISTORY_MSG_33;Powtórzenia dekonwolucji +HISTORY_MSG_34;Zapobiegaj przycinaniu kolorów +HISTORY_MSG_35;Limit nasycenia +HISTORY_MSG_36;Limit nasycenia +HISTORY_MSG_37;Wzmocnienie koloru +HISTORY_MSG_38;Metoda balansu bieli +HISTORY_MSG_39;Temperatura koloru +HISTORY_MSG_40;Odcień balansu bieli +HISTORY_MSG_41;Przesunięcie koloru "A" +HISTORY_MSG_42;Przesunięcie koloru "B" +HISTORY_MSG_43;Odszumianie luminancji +HISTORY_MSG_44;Promień odszumiania lum. +HISTORY_MSG_45;Tolerancja krawędzi odszumiania lum. +HISTORY_MSG_46;Odszumianie koloru +HISTORY_MSG_47;Promień odszumiania kolorowego +HISTORY_MSG_48;Tolerancja krawędzi odszumiania kol. +HISTORY_MSG_49;Odszumianie koloru z czuł. kraw. +HISTORY_MSG_50;Narzędzie światła/cienie +HISTORY_MSG_51;Wzmocnienie świateł +HISTORY_MSG_52;Wzmocnienie cieni +HISTORY_MSG_53;Szerokość tonalna świateł +HISTORY_MSG_54;Szerokość tonalna cieni +HISTORY_MSG_55;Kontrast lokalny +HISTORY_MSG_56;Promień świateł/cieni +HISTORY_MSG_57;Surowy obrót +HISTORY_MSG_58;Odbicie w poziomie +HISTORY_MSG_59;Odbicie w pionie +HISTORY_MSG_60;Obrót +HISTORY_MSG_61;Obrót +HISTORY_MSG_62;Korekcja dystorsji obiektywu +HISTORY_MSG_63;Zapamiętaj wybrany +HISTORY_MSG_64;Kadrowanie zdjęcia +HISTORY_MSG_65;Korekcja aberracji +HISTORY_MSG_66;Odzyskiwanie prześwietleń +HISTORY_MSG_67;Siła odzyskiwania prześwietleń +HISTORY_MSG_68;Metoda odzyskiwania Prześwietleń +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;Korekcja winietowania +HISTORY_MSG_73;Mikser kanałów +HISTORY_MSG_74;Skala zmiany rozmiaru +HISTORY_MSG_75;Metoda zmiany rozmiaru +HISTORY_MSG_76;Metadane Exif +HISTORY_MSG_77;Metadane IPTC +HISTORY_MSG_78;Data specified for resize +HISTORY_MSG_79;Szerokość skalowania +HISTORY_MSG_80;Wysokość skalowania +HISTORY_MSG_81;Skalowanie włączone +HISTORY_MSG_82;Profil zmieniony +HISTORY_MSG_83;Wysokiej jakości niedoświetlenia/prześwietlenia +HISTORY_MSG_84;Korekcja perspektywy +HISTORY_MSG_85;Współczynniki wavelet +HISTORY_MSG_86;Korektor wavelet +HISTORY_MSG_87;Impulsowa redukcja szumu +HISTORY_MSG_88;Próg impulsowej redukcji szumu +HISTORY_MSG_89;Redukcja szumu +HISTORY_MSG_90;NR - luminacja +HISTORY_MSG_91;NR - chrominacja +HISTORY_MSG_92;NR - gamma +HISTORY_MSG_93;Kontrast wg. poziomu wartości detali +HISTORY_MSG_94;Kontrast wg. poziomu detali +HISTORY_MSG_95;Nasycenie +HISTORY_MSG_96;'a' krzywa +HISTORY_MSG_97;'b' krzywa +HISTORY_MSG_98;Algorytm demozaikowania +HISTORY_MSG_99;Filtrowania gorących/martwych pikseli +HISTORY_MSG_100;Nasycenie RGB +HISTORY_MSG_101;HSV EQ -- Odcień +HISTORY_MSG_102;HSV EQ -- Nasycenie +HISTORY_MSG_103;HSV EQ -- Mocy Światła Białego +HISTORY_MSG_104;HSV korektor +HISTORY_MSG_105;Usuwanie widma +HISTORY_MSG_106;Promień dla usuwania widma +HISTORY_MSG_107;Próg dla usuwania widma +HISTORY_MSG_108;Próg kompresji prześwietleń +HISTORY_MSG_109;Wymiary obwodu +HISTORY_MSG_110;Skalowanie dotyczy +HISTORY_MSG_111;Unikaj przycinania koloru +HISTORY_MSG_112;Ogranicznik nasycenia +HISTORY_MSG_113;Ograniczenie nasyczenia +HISTORY_MSG_114;Liczba powtórzeń DCB +HISTORY_MSG_115;Liczba powtórzeń zapobiegania fałszowaniu koloru +HISTORY_MSG_116;Rozszerzone DCB +HISTORY_MSG_117;Korekcja czerwonej aberracji chromatycznej +HISTORY_MSG_118;Korekcja niebieskiej aberracji chromatycznej +HISTORY_MSG_119;Odszumianie liniowe +HISTORY_MSG_120;Próg wyrównania zieleni +HISTORY_MSG_121;Autokorekta aberracji chromatycznej +HISTORY_MSG_122;Automatyczna czarna klatka +HISTORY_MSG_123;Plik czarnej klatki +HISTORY_MSG_124;Liniowa korekcja ekspozycji +HISTORY_MSG_125;Korekcja ekspozycji z zapobieganiem prześwietleniom +HISTORY_MSG_126;Plik pustego pola +HISTORY_MSG_127;Autowybór pustego pola +HISTORY_MSG_128;Promień rozmycia dla pustego pola +HISTORY_MSG_129;Typ rozmycia dla pustego pola +HISTORY_MSG_130;Automatyczna korekcja dystorsji +HISTORY_MSG_131;Redukcja szumu kanału Luma +HISTORY_MSG_132;Redukcja szumu kanału Chroma +HISTORY_MSG_133;Gamma +HISTORY_MSG_134;Pozycja gamma +HISTORY_MSG_135;Dowolna gamma +HISTORY_MSG_136;Nachylenie gamma +HISTORY_MSG_137;Czerń - poziom zieleni 1 +HISTORY_MSG_138;Czerń - poziom czerwieni +HISTORY_MSG_139;Czerń - poziom niebieskiego +HISTORY_MSG_140;Czerń - poziom zieleni 2 +HISTORY_MSG_141;Czerń - poziom zieleń 1+2 +HISTORY_MSG_142;Powtórzenia wyostrzania krawędzi +HISTORY_MSG_143;Siła wyostrzania krawędzi +HISTORY_MSG_144;Siła mikrokontrastu +HISTORY_MSG_145;Jednolitość mikrokontrastu +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ść - Odcienie pastelowe +HISTORY_MSG_153;Jaskrawość - Odcienie nasycone +HISTORY_MSG_154;Jaskrawość - Zachowaj odcienie skóry +HISTORY_MSG_155;Jaskrawość - Zapobiegaj zmianom kolorów +HISTORY_MSG_156;Jaskrawość - Połącz odcienie pastelowe i nasycone +HISTORY_MSG_157;Jaskrawość - Próg odcieni pastelowych/nasyconych +HISTORY_MSG_158;Siła +HISTORY_MSG_159;Wyszukanie krawędzi +HISTORY_MSG_160;Skala +HISTORY_MSG_161;Powtarzanie rozważania +HISTORY_MSG_162;Tone Mapping +HISTORY_MSG_163;Krzywe RGB - R +HISTORY_MSG_164;Krzywe RGB - G +HISTORY_MSG_165;Krzywe RGB - B +HISTORY_MSG_166;Ustawienia neutralne +HISTORY_MSG_167;Tonacja B&W +HISTORY_MSG_168;Krzywa 'CC' +HISTORY_MSG_169;Krzywa 'CH' +HISTORY_MSG_170;Krzywa jaskrawości +HISTORY_MSG_171;Krzywa 'LC' +HISTORY_MSG_172;Ogranicz LC do odcieni skóry oraz czerwieni +HISTORY_MSG_173;NR - Szczegóły Luminancji +HISTORY_MSG_174;CIECAM02 +HISTORY_MSG_175;CAM02 - Siła adaptacji chrom. +HISTORY_MSG_176;CAM02 - Ciemność otoczenia widowni +HISTORY_MSG_177;CAM02 - Adaptacja luminancji sceny +HISTORY_MSG_178;CAM02 - Adaptacja luminancji widowni +HISTORY_MSG_179;CAM02 - Model +HISTORY_MSG_180;CAM02 - Jasność (J) +HISTORY_MSG_181;CAM02 - Chroma (C) +HISTORY_MSG_182;CAM02 - Automatyczne CAT02 +HISTORY_MSG_183;CAM02 - Kontrast (J) +HISTORY_MSG_184;CAM02 - Scena o ciemnym otoczeniu +HISTORY_MSG_185;CAM02 - Kontrola gamy +HISTORY_MSG_186;CAM02 - Algorytm +HISTORY_MSG_187;CAM02 - Ochrona odcieni skóry i czerwieni +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 - Hue (kąt) +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 - Pokaż wyjściowy histogram CIECAM02 za krzywymi +HISTORY_MSG_200;CAMO2 - Tone mapping za pomocą CIECAM02 Q +HISTORY_MSG_201;NR - Różnica chrominancji czerwonych +HISTORY_MSG_202;NR - Różnica chrominancji niebieskich +HISTORY_MSG_203;NR - Metoda +HISTORY_MSG_204;Kroki poprawy LMMSE +HISTORY_MSG_205;CAM02 gorące/uszkodzone piksele +HISTORY_MSG_206;CAT02 - Automatyczna adaptacja do sceny +HISTORY_MSG_207;Krzywa usuwania widma +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_SAVEAS;Jako... +MAIN_BUTTON_SAVE;Zapisz obraz +MAIN_BUTTON_SAVE_TOOLTIP;Zapisz bieżące zdjęcieCtrl+S +MAIN_BUTTON_SENDTOEDITOR;Wyślij do edytora +MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Otwórz bieżące zdjęcie w zewnętrznym edytorze Ctrl+E +MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Pokaż/Ukryj wszystkie panele boczne m +MAIN_BUTTON_UNFULLSCREEN;Zwolnij ekran +MAIN_FRAME_BATCHQUEUE;Kolejka +MAIN_FRAME_BATCHQUEUE_TOOLTIP;Przetwarzanie wsadowe Ctrl-F3 +MAIN_FRAME_EDITOR;Edytor +MAIN_FRAME_EDITOR_TOOLTIP; Edytor Ctrl-F4 +MAIN_FRAME_FILEBROWSER;Menedżer plików +MAIN_FRAME_FILEBROWSER_TOOLTIP; Przeglądanie plików 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;Alt-c +MAIN_TAB_DETAIL;Szczegóły +MAIN_TAB_DETAIL_TOOLTIP;Alt-d +MAIN_TAB_DEVELOP; Przetwarzanie +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPORT; Eksport +MAIN_TAB_EXPOSURE;Ekspozycja +MAIN_TAB_EXPOSURE_TOOLTIP;Alt-e +MAIN_TAB_FILTER; Filter +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadane +MAIN_TAB_METADATA_TOOLTIP;Alt-m +MAIN_TAB_RAW;RAW +MAIN_TAB_RAW_TOOLTIP;Alt-r +MAIN_TAB_TAGGING;Tagowanie +MAIN_TAB_TRANSFORM;Transformacje +MAIN_TAB_TRANSFORM_TOOLTIP;Alt-t +MAIN_TOOLTIP_BACKCOLOR0;Kolor tła podglądu: Tematyczny\nSkrót: 8 +MAIN_TOOLTIP_BACKCOLOR1;Kolor tła podglądu: Czarny\nSkrót: 9 +MAIN_TOOLTIP_BACKCOLOR2;Kolor tła podglądu: Biały\nSkrót: 0 +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ą, klawisz skrótu: H) +MAIN_TOOLTIP_INDCLIPPEDH;Pokaż prześwietlenia +MAIN_TOOLTIP_INDCLIPPEDS;Pokaż niedoświetlenia +MAIN_TOOLTIP_PREVIEWB;Podgląd kanału niebieskiego\nSkrót: b +MAIN_TOOLTIP_PREVIEWFOCUSMASK;Podgląd maski ostrości (beta)\nSkrót: Shift-F\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\n0.299*R + 0.587*G + 0.114*B\nSkrót: v +MAIN_TOOLTIP_PREVIEWR;Podgląd kanału czerwonego\nSkrót: r +MAIN_TOOLTIP_QINFO;Informacje o pliku +MAIN_TOOLTIP_SHOWHIDELP1;Pokaż/Ukryj lewy panel l +MAIN_TOOLTIP_SHOWHIDERP1;Pokaż/Ukryj prawy panel Alt-l +MAIN_TOOLTIP_SHOWHIDETP1;Pokaż/Ukryj górny panel Shift-l +MAIN_TOOLTIP_THRESHOLD;Próg +MAIN_TOOLTIP_TOGGLE;Przełącz widok Przed/Po B +NAVIGATOR_B_NA;B = n/a +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_LAB_A_NA;A = n/a +NAVIGATOR_LAB_A_VALUE;A = %1 +NAVIGATOR_LAB_B_NA;B = n/a +NAVIGATOR_LAB_B_VALUE;B = %1 +NAVIGATOR_LAB_L_NA;L = n/a +NAVIGATOR_LAB_L_VALUE;L = %1 +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_V_VALUE;V = %1 +NAVIGATOR_XY_FULL;Szerokość = %1, Wysokość = %2 +NAVIGATOR_XY_NA;x = n/a, y = n/a +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 AbChr +PARTIALPASTE_CHANNELMIXER;Mikser kanałów +PARTIALPASTE_COARSETRANS;Rotacja/odwrócenie o 90 stopni +PARTIALPASTE_COLORAPP;CIE Color Appearance Model 2002 +PARTIALPASTE_COLORGROUP;Ustawienia związane z kolorem +PARTIALPASTE_COMMONTRANSFORMPARAMS;Autouzupełnienie +PARTIALPASTE_COMPOSITIONGROUP;Ustawienia kompozycji +PARTIALPASTE_CROP;Przytnij +PARTIALPASTE_DARKFRAMEAUTOSELECT;Auto wybór czarnej klatki +PARTIALPASTE_DARKFRAMEFILE;Plik 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;Zmień dane Exif +PARTIALPASTE_EXPOSURE;Ekspozycja +PARTIALPASTE_FLATFIELDAUTOSELECT;FF autowybór +PARTIALPASTE_FLATFIELDBLURRADIUS;FF promień rozmycia +PARTIALPASTE_FLATFIELDBLURTYPE;FF typ rozmycia +PARTIALPASTE_FLATFIELDFILE;Plik pustego pola (FF) +PARTIALPASTE_HSVEQUALIZER;Korektor HSV +PARTIALPASTE_ICMGAMMA;Gamma wyjściowa +PARTIALPASTE_ICMSETTINGS;Ustawienia ICM +PARTIALPASTE_IMPULSEDENOISE;Impulsowa redukcja szumu +PARTIALPASTE_IPTCINFO;Informacje IPTC +PARTIALPASTE_LABCURVE;Regulacje Lab +PARTIALPASTE_LENSGROUP;Ustawienia związane z obiektywem +PARTIALPASTE_LENSPROFILE;Profil korekcji obiektywu LCP +PARTIALPASTE_LUMACURVE;Krzywa obiektywu +PARTIALPASTE_METAICMGROUP;Metadane/Ustawienia ICM +PARTIALPASTE_PERSPECTIVE;Perspektywa +PARTIALPASTE_PREPROCESS_GREENEQUIL;Wyrównanie zieleni +PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Usuń gorące/uszkodzone (świece) piksele +PARTIALPASTE_PREPROCESS_LINEDENOISE;Liniowa redukcja szumu +PARTIALPASTE_RAWCACORR_AUTO;Autokorekta aberracji chromatycznej +PARTIALPASTE_RAWCACORR_CABLUE;AbChr niebieski +PARTIALPASTE_RAWCACORR_CARED;AbChr czerwony +PARTIALPASTE_RAWEXPOS_BLACK;Poziom czerni +PARTIALPASTE_RAWEXPOS_LINEAR;Współczynnik liniowej korekcji bieli RAW +PARTIALPASTE_RAWEXPOS_PRESER;Czujnik prześwietlania bieli RAW (EV) +PARTIALPASTE_RAWGROUP;Ustawienia RAW +PARTIALPASTE_RAW_ALLENHANCE;Zastosuj redukcję szumu i artefaktów po demozaikowaniu +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;Zmień rozmiar +PARTIALPASTE_RGBCURVES;Krzywe RGB +PARTIALPASTE_ROTATION;Rotacja +PARTIALPASTE_SHADOWSHIGHLIGHTS;Cienie/Światła +PARTIALPASTE_SHARPENEDGE;Krawędzie +PARTIALPASTE_SHARPENING;Wyostrzanie +PARTIALPASTE_SHARPENMICRO;Mikrokontrast +PARTIALPASTE_VIBRANCE;Jaskrawość +PARTIALPASTE_VIGNETTING;Korekcja winiety +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_BLINKCLIPPED;Mrugające prześwietlenia +PREFERENCES_CACHECLEARALL;Wyczyść wszystko +PREFERENCES_CACHECLEARPROFILES;Wyczyść profile +PREFERENCES_CACHECLEARTHUMBS;Wyczyść miniaturki +PREFERENCES_CACHEFORMAT1;Własnościwe (szybciej i z lepszą jakością) +PREFERENCES_CACHEFORMAT2;JPEG (mniejsze zużycie dysku) +PREFERENCES_CACHEMAXENTRIES;Maksymalna liczba wpisów w pamięci podręcznej +PREFERENCES_CACHEOPTS;Opcje pamięci podręcznej +PREFERENCES_CACHETHUMBFORM;Format miniatur w 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_CLEARDLG_LINE1;Czyszczenie pamięci podręcznej +PREFERENCES_CLEARDLG_LINE2;Może to potrwać kilka sekund. +PREFERENCES_CLEARDLG_TITLE;Prosze czekać +PREFERENCES_CLIPPINGIND;Pokazywanie prześwietleń +PREFERENCES_CMETRICINTENT;Sposób odwzorowania barw +PREFERENCES_CUSTPROFBUILDHINT;Plik wykonywalny (lub skrypt) uruchamiany w celu wygenerowania profilu początkowego dla zdjęcia.\nOtrzymuje następujące parametry linii poleceń przydatne do wygenerowania pliku .pp3 :\n[Path RAW/JPG] [Path default profile] [f-no] [exposure in secs] [focal length in mm] [ISO] [Lens] [Camera] +PREFERENCES_CUSTPROFBUILDPATH;Ścieżka pliku wykonywalnego +PREFERENCES_CUSTPROFBUILD;Zewnętrzny kreator profilu dla zdjęcia +PREFERENCES_CUTOVERLAYBRUSH;Maska koloru/przeźroczystości +PREFERENCES_D50;5000K +PREFERENCES_D55;5500K +PREFERENCES_D60;6000K +PREFERENCES_D65;6500K +PREFERENCES_DARKFRAMEFOUND;Znaleziono +PREFERENCES_DARKFRAMESHOTS;kadry +PREFERENCES_DARKFRAMETEMPLATES;szablony +PREFERENCES_DARKFRAME;Czarna klatka +PREFERENCES_DATEFORMATFRAME;Format daty +PREFERENCES_DATEFORMATHINT;Dozwolone są następujące kody formatujące:\n%y : year\n%m : miesiąc\n%d : dzień\n\nPrzykładowy węgierski format daty to:\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_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_GTKTHEME;Domyślny temat GTK +PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogram w lewym panelu +PREFERENCES_HLTHRESHOLD;Próg dla prześwietleń +PREFERENCES_ICCDIR;Katalog z profilami 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ę raw, jeśli nieedytowany +PREFERENCES_LANGAUTODETECT;Użycie systemowych ustawień językowych +PREFERENCES_MENUGROUPEXTPROGS;Grupuj "Otwórz za pomocą" +PREFERENCES_MENUGROUPFILEOPERATIONS;Grupuj operacje plików +PREFERENCES_MENUGROUPLABEL;Grupuj operacje etykiet +PREFERENCES_MENUGROUPPROFILEOPERATIONS;Grupuj operacje profili +PREFERENCES_MENUGROUPRANK;Grupuj operacje oceny +PREFERENCES_MENUOPTIONS;Opcje menu +PREFERENCES_METADATA;Metadane +PREFERENCES_MONITORICC;Profil monitora +PREFERENCES_MULTITABDUALMON;Tryb wielu zakładek, jeżeli dostępny drugi monitor +PREFERENCES_MULTITAB;Tryb wielu zakładek +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, ...\n\nKody formatujące odnoszą się do katalogów i podkatalogów w ścieżce pliku raw.\n\nPrzykładowo, jeżeli otworzono plik /home/tom/image/02-09-2006/dsc0012.nef, znaczenie kodów formatujących będzie następujące:\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\nBy zapisać plik wyjściowy obok pliku orginalnego, proszę wpisać:\n%p1/%f\n\nJeżeli zdjęcia mają zostać umieszczone w nowym katalog 'converted' znajdującym się w katalogu źródłowym, proszę wpisać:\n%p1/converted/%f\n\nJeżeli zdjęcia mają zostać umieszczone w katalogu '/home/tom/converted' zgrupowane w podkatalogi z datą w nazwie, proszę wpisać:\n%p2/converted/%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_PANFACTORFRAME;Przyśpieszenie podczas przesuwania podglądu +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 Usuwania Szumów +PREFERENCES_RGBDTL_TOOLTIP;Usuwanie Szumów potrzebuje 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_SHOWPROFILESELECTOR;Umożliw wybór profilu +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 Window należy stosować "SystemDefault", "SystemAsterisk" itp. dla dźwięków systemowych. +PREFERENCES_SND_LNGEDITPROCDONE;Praca edytora wykonana +PREFERENCES_SND_TRESHOLDSECS;po sekundach +PREFERENCES_SQUAREDETAILWINDOW;Mniejsze okno lupy (szybsze) +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_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_FILEDLGFILTERANY;Wszystkie pliki +PROFILEPANEL_FILEDLGFILTERPP;Profile przetwarzania końcowego +PROFILEPANEL_LABEL;Profil przetwarzania końcowego +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 RT.\n\nWyłączone: profile zostaną zastosowane takie, jakie są, zmieniając tylko te wartości, które zawierają. +PROFILEPANEL_PASTEPPASTE;Parametry do wklejenia +PROFILEPANEL_PCUSTOM;Ręczny +PROFILEPANEL_PFILE;Z pliku +PROFILEPANEL_PLASTSAVED;Ostatnio zapisany +PROFILEPANEL_SAVEDLGLABEL;Zapisz parametry przetwarzania końcowego... +PROFILEPANEL_SAVEPPASTE;Parametry do zapisania +PROFILEPANEL_TOOLTIPCOPY;Skopiuj aktualny profil do schowka +PROFILEPANEL_TOOLTIPLOAD;Ładuj profil z pliku +PROFILEPANEL_TOOLTIPPASTE;Wklej profil ze schowka +PROFILEPANEL_TOOLTIPSAVE;Zapisz aktualny profil +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 parametry 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_LOADING;Wczytywanie pliku... +PROGRESSDLG_PROCESSING;Przetwarzanie zdjęcia... +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profil zmieniony w przeglądarce +PROGRESSDLG_SAVING;Zapisywanie pliku... +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_JPGFILTER;Pliki 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_TIFFFILTER;Pliki TIFF +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 (klawisz skrótu: C) +TOOLBAR_TOOLTIP_HAND;Przesuń (klawisz skrótu: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Wyprostuj obraz (klawisz skrótu: S) +TOOLBAR_TOOLTIP_WB;Wskaż balans bieli (klawisz skrótu: W) +TP_CACORRECTION_BLUE;Niebieski +TP_CACORRECTION_LABEL;Korekcja aberracji +TP_CACORRECTION_RED;Czerwony +TP_CHMIXER_BLUE;Niebieski +TP_CHMIXER_GREEN;Zielony +TP_CHMIXER_LABEL;Mikser kanałów +TP_CHMIXER_RED;Czerwony +TP_CHROMATABERR_LABEL;Aberracja chromatyczna +TP_COARSETRAF_DEGREE;stopnie: +TP_COARSETRAF_TOOLTIP_HFLIP;Odbij w poziomie +TP_COARSETRAF_TOOLTIP_ROTLEFT;Obróć w lewo +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Obróć w prawo +TP_COARSETRAF_TOOLTIP_VFLIP;Odbij w pionie +TP_COLORAPP_ADAPTSCENE;Adaptacja luminancji sceny +TP_COLORAPP_ADAPTSCENE_TOOLTIP;Bezwzględna luminancja sceny (cd/m²).\n 1)Obliczona za pomocą Exif:\nCzas naświetlania - ISO - Apertura - Korekta ekspozycji EV.\n2)Obliczona również na podstawie punktu bieli raw oraz korekty ekspozycji w RT +TP_COLORAPP_ADAPTVIEWING;Adaptacja luminancji widowni (cd/m²) +TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Bezwzględna luminancja widowni\n(zazwyczaj 16cd/m²) +TP_COLORAPP_ADAP_AUTO_TOOLTIP;Jesli zaznaczone (polecamy), RT 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;Jasność + Chroma (JC) +TP_COLORAPP_ALGO_JS;Jasność + 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 1=mediana 2=gaussa.\n\nTe anomalie wynikają z limitacji CIECAM02. Można również dostroić obraz aby uniknąć bardzo ciemnych miejsc. +TP_COLORAPP_BRIGHT;Jasność (Q) +TP_COLORAPP_BRIGHT_TOOLTIP;Jasność w CIECAM02 bierze pod uwagę luminancję bieli i różni się od jasności Lab 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 Lab oraz RGB. +TP_COLORAPP_CHROMA_S;Nasycenie (S) +TP_COLORAPP_CHROMA_S_TOOLTIP;Nasycenie w CIECAM02 różni się od nasycenia Lab oraz RGB. +TP_COLORAPP_CHROMA_TOOLTIP;Chroma w CIECAM02 różni się od chromy Lab 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 Lab oraz RGB. +TP_COLORAPP_CONTRAST_TOOLTIP;Kontrast w CIECAM02 dla suwaka J, różni się od kontrastu Lab oraz RGB. +TP_COLORAPP_CURVEEDITOR1;Krzywa tonalna 1 +TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Pokazuje histogram L (Lab) 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 (Lab) przed CIECAM02.\nJeśli opcja "Pokaż histogramy wyjściowe CIECAM02 za krzywymi" jest włączona, pokazuje histogram C, s oraz 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 korektach CIECAM02.\nTen wybór nie ma wpływu głównego histogramu.\n\nKiedy opcja jest wyłączona, histogramy za krzywymi CIECAM02 pokazują wartości Lab przed korektami CIECAM02. +TP_COLORAPP_DEGREE_AUTO_TOOLTIP;Jeśli opcja jest zaznaczona (zalecane), RT kalkuluje wartość optymalną, która jest potem użyta przez CAT02 oraz przez cale CIECAM02.\nAby ustawić wartość ręcznie, odznacz opcję (wartości powyżej 65 zalecane) +TP_COLORAPP_DEGREE_TOOLTIP;Siła CIE Chromatic Adaptation Transform 2002 +TP_COLORAPP_GAMUT;Kontrola gamy (Lab) +TP_COLORAPP_GAMUT_TOOLTIP;Włącz kontrolę gamy w trybie Lab +TP_COLORAPP_HUE;Hue (h) +TP_COLORAPP_HUE_TOOLTIP;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 Lab oraz RGB +TP_COLORAPP_MODEL;Model punktu bieli (WB) +TP_COLORAPP_MODEL_TOOLTIP;WB [RT] + [wyjściowy]:\nBalans bieli RT jest użyty dla sceny, CIECAM02 jest ustawione na D50, balans bieli urządzenia wyjściowego ustawiony jest w Ustawieniach > Zarządzanie Kolorami\n\nWB [RT+CAT02] + [wyjściowe]:\nUstawienia balansu bieli RT są używane przez CAT02, i balans bieli urządzenia wyjściowego jest ustawione w Ustawieniach. +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;Wyostrzanie, Kontrast wg. Poziomu Detali, Mikrokontrast & Usuwanie Widma za pomocą Q/C +TP_COLORAPP_SHARPCIE_TOOLTIP;Wyostrzanie, Kontrast wg. Poziomu Detali, Mikrokontrast & Usuwanie Widma wykorzystają CIECAM02 jeśli włączone. +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)\nObraz się nie zmieni.\n\nPrzyćmione:\nPrzyćmione otoczenie (TV)\nObraz stanie się troszkę ciemniejszy.\n\nCiemne:\nCiemne otoczenie (projektor)\nObraz stanie się jeszczę ciemniejszy.\n\nBardzo Ciemne:\nBardzo ciemne otoczenie (cut-sheet)\nObraz 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 Lab, 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;WB [RT+CAT02] + [wyjściowy] +TP_COLORAPP_WBRT;WB [RT] + [wyjściowy] +TP_COLORBOOST_ACHANNEL;kanał "a" +TP_COLORBOOST_AMOUNT;Stopień +TP_COLORBOOST_AVOIDCOLORCLIP;Unikaj przycinania kolorów +TP_COLORBOOST_BCHANNEL;kanał "b" +TP_COLORBOOST_CHANNEL;Kanał +TP_COLORBOOST_CHSEPARATE;oddzielnie +TP_COLORBOOST_ENABLESATLIMITER;Limit nasycenia +TP_COLORBOOST_LABEL;Wzmocnienie koloru +TP_COLORBOOST_SATLIMIT;Limit nasycenia +TP_COLORDENOISE_EDGESENSITIVE;Czułość krawędzi +TP_COLORDENOISE_EDGETOLERANCE;Tolerancja krawędzi +TP_COLORDENOISE_LABEL;Odszumianie koloru +TP_COLORDENOISE_RADIUS;Promień +TP_COLORSHIFT_BLUEYELLOW;Błękit-żółty +TP_COLORSHIFT_GREENMAGENTA;Zieleń-magenta +TP_COLORSHIFT_LABEL;Przesunięcie koloru +TP_CROP_DPI;DPI= +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_GTHARMMEANS1;Złoty podział 1 +TP_CROP_GTHARMMEANS2;Złoty podział 2 +TP_CROP_GTHARMMEANS3;Złoty podział 3 +TP_CROP_GTHARMMEANS4;Złoty podział 4 +TP_CROP_GTNONE;Nic +TP_CROP_GTRULETHIRDS;Trójpodział +TP_CROP_GUIDETYPE;Typ pomocy: +TP_CROP_H;W +TP_CROP_LABEL;Kadrowanie +TP_CROP_PPI;PPI= +TP_CROP_SELECTCROP;Wybierz kadr +TP_CROP_W;S +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_DETAIL_AMOUNT;Siła +TP_DIRPYRDENOISE_BLUE;Różnica chrominancji niebieskich +TP_DIRPYRDENOISE_CHROMA;Chrominacja +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_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_LDETAIL;Szczegółowość Luminancji +TP_DIRPYRDENOISE_LUMA;Luminacja +TP_DIRPYRDENOISE_METHOD;Metoda +TP_DIRPYRDENOISE_METHOD_TOOLTIP;Dla obrazów raw można używać metody RGB oraz Lab.\n\nDla obrazów nie-raw metoda Lab zostanie użyta niezależnie od wyboru. +TP_DIRPYRDENOISE_PERF;Tryb RGB (obrazy raw) +TP_DIRPYRDENOISE_RED;Różnica chrominancji czerwonych +TP_DIRPYRDENOISE_RGB;RGB +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_THRESHOLD;Próg +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 Lab (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_EQUALIZER_CONTRAST_MINUS;Kontrast- +TP_EQUALIZER_CONTRAST_PLUS;Kontrast+ +TP_EQUALIZER_FINEST;delikatnie +TP_EQUALIZER_LABEL;Korektor Wavelet +TP_EQUALIZER_LARGEST;zgrubnie +TP_EQUALIZER_NEUTRAL;Neutralne +TP_EXPOSCORR_LABEL;Punkt bieli raw +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 świateł +TP_EXPOSURE_COMPRHIGHLIGHTS;Kompresja świateł +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;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_EXPO_AFTER; Po interpolacji (przed konwersją RGB) +TP_FLATFIELD_AUTOSELECT;Autowybór +TP_FLATFIELD_BLURRADIUS;Promień rozmycia +TP_FLATFIELD_BLURTYPE;Typ rozmycia +TP_FLATFIELD_BT_AREA;Obszar +TP_FLATFIELD_BT_HORIZONTAL;Poziome +TP_FLATFIELD_BT_VERTHORIZ;Poz. + Pion. +TP_FLATFIELD_BT_VERTICAL;Pionowe +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_HLREC_BLEND;Mieszanie +TP_HLREC_CIELAB;Mieszanie koloru CIELab +TP_HLREC_COLOR;Propagacja koloru +TP_HLREC_LABEL;Odzyskiwanie prześwietleń +TP_HLREC_LUMINANCE;Odzyskiwanie luminancji +TP_HLREC_METHOD;Metoda: +TP_HSVEQUALIZER1;Czerwony +TP_HSVEQUALIZER2;Żółty +TP_HSVEQUALIZER3;Limonka +TP_HSVEQUALIZER4;Zielony +TP_HSVEQUALIZER5;Cyjan +TP_HSVEQUALIZER6;Niebieski +TP_HSVEQUALIZER7;Purpurowy +TP_HSVEQUALIZER8;Magenta +TP_HSVEQUALIZER_CHANNEL;Kanał HSV +TP_HSVEQUALIZER_HUE;H +TP_HSVEQUALIZER_LABEL;Korektor 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_FILEDLGFILTERANY;Wszystkie pliki +TP_ICM_FILEDLGFILTERICM;Pliki z profilami ICC +TP_ICM_GAMMABEFOREINPUT;Profil stosuje korekcję gamma +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;Ręczny +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;No ICM: Wyjście sRGB +TP_ICM_OUTPUTPROFILE;Profil wyjściowy +TP_ICM_PREFERREDPROFILE;Preferowany profil DCP +TP_ICM_PREFERREDPROFILE_1;Światło dzienne +TP_ICM_PREFERREDPROFILE_2;Wolfram +TP_ICM_PREFERREDPROFILE_3;Jarzeniowe +TP_ICM_PREFERREDPROFILE_4;Flash +TP_ICM_SAVEREFERENCE;Zapisz obraz wzorcowy dla profilowania +TP_ICM_TONECURVE;Użyj krzywą tonalną z DCP +TP_ICM_TONECURVE_TOOLTIP;Włącz aby umożliwić użycie krzywej tonalnej która może się znajdować w profilu DCP. +TP_ICM_WORKINGPROFILE;Profil roboczy +TP_IMPULSEDENOISE_LABEL;Impulsowa redukcja szumu +TP_IMPULSEDENOISE_THRESH;Próg impulsowej redukcji szumu +TP_LABCURVE_AVOIDCOLORCLIP;Unikaj przycinania koloru +TP_LABCURVE_AVOIDCOLORSHIFT;Unikaj zmian koloru +TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Umieszcza kolory w gamie roboczej przestrzeni kolorów i stosuje korektę Munsell'a +TP_LABCURVE_BRIGHTNESS;Jasność +TP_LABCURVE_BWTONING;Tonowanie B&W +TP_LABCURVE_BWTONING_TIP;Kiedy opcja jest włączona, Chromatyczność Lab oraz krzywe CC, CH i LC nie mają wpływu na obraz.\nTonowanie można wykonać poprzez zmianę krzywych a oraz b. +TP_LABCURVE_CHROMATICITY;Chromatyczność +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ść C=f(C).\n\nPokazuje histogram chromatyczności przed korektą krzywych.\nEfekt końcowy jest przedstawiony w głównym histogramie. +TP_LABCURVE_CURVEEDITOR_CH;CH +TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromatyczność według odcieni +TP_LABCURVE_CURVEEDITOR_LC;LC +TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminancja według chromatyczności +TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminancja Lab L=f(L).\n\nPokauje histogram L przed korektą krzywych.\nEfekt końcowy jest przedstawiony w głównym histogramie. +TP_LABCURVE_ENABLESATLIMITER;Limitowanie nasycenia +TP_LABCURVE_LABEL;Regulacja Lab +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_LABCURVE_SATLIMIT;Limit nasycenia +TP_LABCURVE_SATURATION;Nasycenie +TP_LENSGEOM_AUTOCROP;Auto przycinanie +TP_LENSGEOM_FILL;Auto wypełnienie +TP_LENSGEOM_LABEL;Obiektywy / Geometria +TP_LENSPROFILE_FILEDLGFILTERLCP;Profile korekcji obiektywów LCP +TP_LENSPROFILE_LABEL;Profil korekcji obiektywu LCP +TP_LENSPROFILE_USECA;Korekja aberacji chromatycznej +TP_LENSPROFILE_USEDIST;Korekcja dystorsji +TP_LENSPROFILE_USEVIGN;Korekcja winietowania +TP_LUMACURVE_BLACKLEVEL;Czerń +TP_LUMACURVE_BRIGHTNESS;Jasność +TP_LUMACURVE_COMPRHIGHLIGHTS;Kompresja świateł +TP_LUMACURVE_COMPRSHADOWS;Kompresja cieni +TP_LUMACURVE_CONTRAST;Kontrast +TP_LUMACURVE_CURVEEDITOR;Krzywa luminancji +TP_LUMACURVE_LABEL;Krzywa luminancji +TP_NEUTRAL;Neutralne +TP_NEUTRAL_TIP;Zresetuj ustawienia do wartości neutralnych +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. Wyżej = bardziej, niżej = mniej. +TP_PREPROCESS_GREENEQUIL;Wyrównanie zieleni +TP_PREPROCESS_HOTDEADPIXFILT;Usuń gorące/uszkodzone (świece) piksele +TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Usuń gorące/uszkodzone (świece) piksele +TP_PREPROCESS_HOTDEADPIXTHRESH;Próg wykrycia gorących/martwych pikseli +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_BLACKONE;Czerń: poziom czerwieni +TP_RAWEXPOS_BLACKS;Poziomy czerni +TP_RAWEXPOS_BLACKTHREE;Czerń: poziom zieleni 2 +TP_RAWEXPOS_BLACKTWO;Czerń: poziom niebieskiego +TP_RAWEXPOS_BLACKZERO;Czerń: poziom zieleni 1 (główny) +TP_RAWEXPOS_LINEAR;Liniowy współczynnik korekcji +TP_RAWEXPOS_PRESER;Czujnik prześwietlenia bieli (EV) +TP_RAWEXPOS_TWOGREEN;Połącz obie zielenie +TP_RAW_ALLENHANCE;Reducja szumu i artefaktów po demozaikowaniu +TP_RAW_DCBENHANCE;Zastosuj poprawę DCB +TP_RAW_DCBITERATIONS;Liczba powtórzeń DCB +TP_RAW_DMETHOD;Metoda +TP_RAW_DMETHOD_PROGRESSBAR;Demosaicowanie %1... +TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Udoskonalanie demosaicowania... +TP_RAW_DMETHOD_TOOLTIP;IGV oraz LMMSE są przeznaczone dla zdjęć raw o wysokim poziomie szumów (wysokie ISO). +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_RESIZE_APPLIESTO;Dotyczy: +TP_RESIZE_BICUBICSF;Bicubic (Miękko) +TP_RESIZE_BICUBICSH;Bicubic (Ostro) +TP_RESIZE_BICUBIC;Bicubic +TP_RESIZE_BILINEAR;Bilinear +TP_RESIZE_CROPPEDAREA;Obszaru przycięcia +TP_RESIZE_DOWNSCALEB;Downscale (Dokładniej) +TP_RESIZE_DOWNSCALEF;Downscale (Szybciej) +TP_RESIZE_FITBOX;Wymiary obwodu +TP_RESIZE_FULLIMAGE;Całego zdjęcia +TP_RESIZE_HEIGHT;Wysokość +TP_RESIZE_H;W: +TP_RESIZE_LABEL;Skalowanie +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;S: +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_AUTOCROP;Auto przycinanie +TP_ROTATE_DEGREE;Stopnie +TP_ROTATE_FILL;Wypełnij +TP_ROTATE_LABEL;Obrót +TP_ROTATE_SELECTLINE;Wyprostuj obraz +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Światła +TP_SHADOWSHLIGHTS_HLTONALW;Szerokość tonalna +TP_SHADOWSHLIGHTS_LABEL;Cienie/Światła +TP_SHADOWSHLIGHTS_LOCALCONTR;Kontrast lokalny +TP_SHADOWSHLIGHTS_RADIUS;Promień +TP_SHADOWSHLIGHTS_SHADOWS;Cienie +TP_SHADOWSHLIGHTS_SHTONALW;Szerokość tonalna +TP_SHARPENEDGE_AMOUNT;Siła +TP_SHARPENEDGE_LABEL;Krawędzie +TP_SHARPENEDGE_PASSES;Powtórzenia +TP_SHARPENEDGE_THREE;Tylko luminacja +TP_SHARPENING_AMOUNT;Siła +TP_SHARPENING_EDRADIUS;Promień +TP_SHARPENING_EDTOLERANCE;Tolerancja +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;Barwy 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ń według odcieni +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 barwy pastelowe na dole oraz nasycone 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;Centrum +TP_VIGNETTING_CENTER_X;Centrum X +TP_VIGNETTING_CENTER_Y;Centrum 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;Ręczny +TP_WBALANCE_DAYLIGHT;Światło dzienne (słonecznie) +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 +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;Otwórz (nową) lupę +ZOOMPANEL_ZOOM100;Powiększ do 100%\nSkrót: z +ZOOMPANEL_ZOOMFITSCREEN;Dopasuj 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. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!FILEBROWSER_POPUPRANK;Rank +!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;'CL' curve +!HISTORY_MSG_247;'LH' curve +!HISTORY_MSG_248;'HH' curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!PARTIALPASTE_CHANNELMIXERBW;Black-and-White +!PARTIALPASTE_GRADIENT;Graduated filter +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PREFERENCES_CUSTPROFBUILDKEYFORMAT;Keys format +!PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Name +!PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID +!PREFERENCES_USEBUNDLEDPROFILES;Use bundled profiles +!PROFILEPANEL_GLOBALPROFILES;Bundled profiles +!PROFILEPANEL_MYPROFILES;My profiles +!PROFILEPANEL_PINTERNAL;Neutral +!TP_BWMIX_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing channel-mixer +!TP_BWMIX_BLUE;Blue +!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;Modify luminance in function of hue\nPay attention to extreme values that may cause artifacts +!TP_BWMIX_CYAN;Cyan +!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 simulate shots taken with a colored filter placed in front of the lens. Colored filters reduce transmission of specific range of colors and correspondingly affect their lightness. E.g. a Red filter darkens Blue skies. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_BLUE;Blue Channel +!TP_BWMIX_GAM_GREEN;Green Channel +!TP_BWMIX_GAM_RED;Red Channel +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each channel RGB +!TP_BWMIX_GREEN;Green +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MAGENTA;Magenta +!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 (filter, channel-mixer) to default +!TP_BWMIX_ORANGE;Orange +!TP_BWMIX_PURPLE;Purple +!TP_BWMIX_RED;Red +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all of the mixer options\nTotal displays the sum of RGB values actually applied:\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 (films, landscape, ...) or manual settings of channel-mixer +!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;Channel-Mixer absolute RGB +!TP_BWMIX_SET_RGBREL;Channel-Mixer relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Channel-Mixer absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Channel-Mixer 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_BWMIX_YELLOW;Yellow +!TP_DIRPYRDENOISE_ENH;Enhanced mode +!TP_DIRPYRDENOISE_ENH_TOOLTIP;Increases noise reduction quality at the expense of a 20% processing time increase +!TP_GENERAL_11SCALE_TOOLTIP;The effect of this tool or some of its sub-component is only visible at 1:1 preview scale. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Rotation anchor point X: -100=left edge, 0=center, +100=right edge +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Rotation anchor point Y: -100=top edge, 0=center, +100=bottom edge +!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 automatic exposure +!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_TOOLTIP;Save the linear TIFF image before the input profile is applied. Result can be used for calibration purposes, 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_PCVIGNETTE_FEATHER;Feather +!TP_PCVIGNETTE_FEATHER_TOOLTIP;Feathering: 0=corners only, 50=halfway to center, 100=to center +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness: 0=rectangle, 50=fitted ellipse, 100=circle +!TP_PCVIGNETTE_STRENGTH;Strength +!TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filter strength in stops (reached in corners) +!TP_SAVEDIALOG_OK_TIP;Shortcut Ctrl-Enter +!TP_SHADOWSHLIGHTS_SHARPMASK;Sharp mask +!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 diff --git a/rtdata/languages/Polish (Latin Characters) b/rtdata/languages/Polish (Latin Characters) new file mode 100644 index 000000000..2df2882bd --- /dev/null +++ b/rtdata/languages/Polish (Latin Characters) @@ -0,0 +1,1476 @@ +#01 2007-12-24 Mateusz Ludwin +#02 2010-01-08 Initial update for 3.0 release by 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 + +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;Cienie +CURVEEDITOR_FILEDLGFILTERANY;Wszystkie pliki +CURVEEDITOR_FILEDLGFILTERCURVE;Pliki z krzywymi +CURVEEDITOR_HIGHLIGHTS;Swiatla +CURVEEDITOR_LIGHTS;Swiatla +CURVEEDITOR_LINEAR;Liniowa +CURVEEDITOR_LOADDLGLABEL;Wczytaj krzywa... +CURVEEDITOR_MINMAXCPOINTS;Min/Max punktow kontrolnych +CURVEEDITOR_NURBS;Kontrolowana +CURVEEDITOR_PARAMETRIC;Parametryczna +CURVEEDITOR_SAVEDLGLABEL;Zapisz krzywa... +CURVEEDITOR_SHADOWS;Cienie +CURVEEDITOR_TOOLTIPCOPY;Skopiuj aktualna krzywa do schowka +CURVEEDITOR_TOOLTIPLINEAR;Zresetuj krzywa do liniowej +CURVEEDITOR_TOOLTIPLOAD;Wczytaj krzywa z pliku +CURVEEDITOR_TOOLTIPPASTE;Wstaw krzywa ze schowka +CURVEEDITOR_TOOLTIPSAVE;Zapisz aktualna krzywa +CURVEEDITOR_TYPE;Typ: +EDITWINDOW_TITLE;Edytuj obraz +EXIFFILTER_APERTURE;Przyslona +EXIFFILTER_CAMERA;Aparat +EXIFFILTER_EXPOSURECOMPENSATION;Korekta Ekspozycji (EV) +EXIFFILTER_FILETYPE;Typ pliku +EXIFFILTER_FOCALLEN;Wartosc ogniskowej +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Obiektyw +EXIFFILTER_METADATAFILTER;Filtr 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_COLORDENOISE;Pomin odszumienie koloru +EXPORT_BYPASS_DEFRINGE;Pomin usuwanie widma +EXPORT_BYPASS_DIRPYRDENOISE;Pomin redukcje szumu +EXPORT_BYPASS_DIRPYREQUALIZER;Pomin kontrast wg. poziomu detali +EXPORT_BYPASS_LUMADENOISE;Pomin odszumianie luminancji +EXPORT_BYPASS_RAW_ALL_ENHANCE;Pomin redukcje szumu i artefaktow po demozaikowaniu +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/swiatel +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 +EXPORT_RESIZEMETHOD;Metoda zmiany rozmiaru +EXTPROGTARGET_1;raw +EXTPROGTARGET_2;wywolane w kolejce +FILEBROWSER_ADDDELTEMPLATE;Dodaj/Usun szablon... +FILEBROWSER_APPLYPROFILE;Zastosuj profil +FILEBROWSER_APPLYPROFILE_PARTIAL;Zastosuj profil (czesciowo) +FILEBROWSER_AUTODARKFRAME;Automatyczne uzycie czarnej klatki +FILEBROWSER_AUTOFLATFIELD;Automatyczne uzycie klatki z pustym polem +FILEBROWSER_BROWSEPATHBUTTONHINT;Prosze kliknac, by 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 pliki? +FILEBROWSER_EMPTYTRASHHINT;Definitywnie usuwa pliki z kosza +FILEBROWSER_EMPTYTRASH;Wyczysc kosz +FILEBROWSER_EXEC_CPB;Uruchom zewnetrzny kreator profilu dla zdjecia +FILEBROWSER_EXTPROGMENU;Otworz za pomoca +FILEBROWSER_FLATFIELD;Puste pole +FILEBROWSER_MOVETODARKFDIR;Przenies do katalogu z czarnymi klatkami +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_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_POPUPOPEN;Otworz +FILEBROWSER_POPUPPROCESSFAST;Dodaj do kolejki szybkiego eksportu +FILEBROWSER_POPUPPROCESS;Umiesc w kolejce do przetwarzania +FILEBROWSER_POPUPPROFILEOPERATIONS;Profile +FILEBROWSER_POPUPREMOVEINCLPROC;Usun z dysku i wynikow przetwarzania +FILEBROWSER_POPUPREMOVE;Usun z systemu plikow +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 okno opcji szukaj +FILEBROWSER_QUERYHINT;Prosze wprowadzic czesc nazwy, bo zlokalizowac plik \nCtrl-f zaznaczenie\nEnter uruchamia wyszukiwanie +FILEBROWSER_QUERYLABEL; Znajdz: +FILEBROWSER_RANK1_TOOLTIP;Ocena 1 *\nSkrot: Shift-1 +FILEBROWSER_RANK2_TOOLTIP;Ocena 2 *\nSkrot: Shift-2 +FILEBROWSER_RANK3_TOOLTIP;Ocena 3 *\nSkrot: Shift-3 +FILEBROWSER_RANK4_TOOLTIP;Ocena 4 *\nSkrot: Shift-4 +FILEBROWSER_RANK5_TOOLTIP;Ocena 5 *\nSkrot: Shift-5 +FILEBROWSER_RENAMEDLGLABEL;Zmien nazwe pliku +FILEBROWSER_RENAMEDLGMSG;Zmien nazwe plki "%1" na: +FILEBROWSER_SELECTDARKFRAME;Wybierz czarna klatke... +FILEBROWSER_SELECTFLATFIELD;Wybierz puste pole... +FILEBROWSER_SHOWCOLORLABEL1HINT;Pokazuje zdjecia z czerwona etykieta Alt-1 +FILEBROWSER_SHOWCOLORLABEL2HINT;Pokazuje zdjecia z zolta etykieta Alt-2 +FILEBROWSER_SHOWCOLORLABEL3HINT;Pokazuje zdjecia z zielona etykieta Alt-3 +FILEBROWSER_SHOWCOLORLABEL4HINT;Pokazuje zdjecia z niebieska etykieta Alt-4 +FILEBROWSER_SHOWCOLORLABEL5HINT;Pokazuje zdjecia z purpurowa etykieta Alt-5 +FILEBROWSER_SHOWDIRHINT;Pokazuje wszystkie zdjecia w katalogu +FILEBROWSER_SHOWEDITEDHINT;Pokazuje edytowane zdjecia 7 +FILEBROWSER_SHOWEDITEDNOTHINT;Pokazuje nieedytowane zdjecia 6 +FILEBROWSER_SHOWEXIFINFO;Pokaz dane EXIF i +FILEBROWSER_SHOWRANK1HINT;Pokazuje zdjecia ocenione na 1 gwiazdke +FILEBROWSER_SHOWRANK2HINT;Pokazuje zdjecia ocenione na 2 gwiazdki +FILEBROWSER_SHOWRANK3HINT;Pokazuje zdjecia ocenione na 3 gwiazdki +FILEBROWSER_SHOWRANK4HINT;Pokazuje zdjecia ocenione na 4 gwiazdki +FILEBROWSER_SHOWRANK5HINT;Pokazuje zdjecia ocenione na 5 gwiazdek +FILEBROWSER_SHOWRECENTLYSAVEDHINT;Pokazuje ostatnio zapisane zdjecia Alt-7 +FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Pokazuje niezapisywane ostatnio zdjecia Alt-6 +FILEBROWSER_SHOWTRASHHINT;Pokazuje zawartosc kosza +FILEBROWSER_SHOWUNCOLORHINT;Pokazuje zdjecia bez kolorowej etykiety Alt-0 +FILEBROWSER_SHOWUNRANKHINT;Pokazuje nieocenione zdjecia +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_USETEMPLATE;Uzyj szablonu: +FILEBROWSER_ZOOMINHINT;Zwieksza rozmiar miniaturek +FILEBROWSER_ZOOMOUTHINT;Zmniejsza rozmiar miniaturek +GENERAL_ABOUT;O programie +GENERAL_AFTER;Przed +GENERAL_AUTO;Automatyczne +GENERAL_BEFORE;Po +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/skalowany +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;Dowolna krzywa +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;Jasnosc +HISTORY_MSG_6;Kontrast +HISTORY_MSG_7;Czern +HISTORY_MSG_8;Kompensacja ekspozycji +HISTORY_MSG_9;Kompresja swiatel +HISTORY_MSG_10;Kompresja cieni +HISTORY_MSG_11;Krzywa tonalna +HISTORY_MSG_12;Automatyczna ekspozycja +HISTORY_MSG_13;Przycinanie ekspozycji +HISTORY_MSG_14;Jasnosc luminancji +HISTORY_MSG_15;Kontrast luminancji +HISTORY_MSG_16;Czern luminancji +HISTORY_MSG_17;Kompr. swiatel luminancji +HISTORY_MSG_18;Kompr. cieni luminancji +HISTORY_MSG_19;Krzywa luminancji +HISTORY_MSG_20;Wyostrzanie +HISTORY_MSG_21;Promien wyostrzania +HISTORY_MSG_22;Sila wyostrzania +HISTORY_MSG_23;Prog wyostrzania +HISTORY_MSG_24;Wyostrz tylko krawedzie +HISTORY_MSG_25;Promien detekcji krawedzi wyostrzania +HISTORY_MSG_26;Tolerancja wyostrzania krawedzi +HISTORY_MSG_27;Kontrola poswiaty wyostrzania +HISTORY_MSG_28;Stopien kontroli poswiaty +HISTORY_MSG_29;Metoda wyostrzania +HISTORY_MSG_30;Promien dekonwolucji +HISTORY_MSG_31;Sila dekonwolucji +HISTORY_MSG_32;Tlumienie dekonwolucji +HISTORY_MSG_33;Powtorzenia dekonwolucji +HISTORY_MSG_34;Zapobiegaj przycinaniu kolorow +HISTORY_MSG_35;Limit nasycenia +HISTORY_MSG_36;Limit nasycenia +HISTORY_MSG_37;Wzmocnienie koloru +HISTORY_MSG_38;Metoda balansu bieli +HISTORY_MSG_39;Temperatura koloru +HISTORY_MSG_40;Odcien balansu bieli +HISTORY_MSG_41;Przesuniecie koloru "A" +HISTORY_MSG_42;Przesuniecie koloru "B" +HISTORY_MSG_43;Odszumianie luminancji +HISTORY_MSG_44;Promien odszumiania lum. +HISTORY_MSG_45;Tolerancja krawedzi odszumiania lum. +HISTORY_MSG_46;Odszumianie koloru +HISTORY_MSG_47;Promien odszumiania kolorowego +HISTORY_MSG_48;Tolerancja krawedzi odszumiania kol. +HISTORY_MSG_49;Odszumianie koloru z czul. kraw. +HISTORY_MSG_50;Narzedzie swiatla/cienie +HISTORY_MSG_51;Wzmocnienie swiatel +HISTORY_MSG_52;Wzmocnienie cieni +HISTORY_MSG_53;Szerokosc tonalna swiatel +HISTORY_MSG_54;Szerokosc tonalna cieni +HISTORY_MSG_55;Kontrast lokalny +HISTORY_MSG_56;Promien swiatel/cieni +HISTORY_MSG_57;Surowy obrot +HISTORY_MSG_58;Odbicie w poziomie +HISTORY_MSG_59;Odbicie w pionie +HISTORY_MSG_60;Obrot +HISTORY_MSG_61;Obrot +HISTORY_MSG_62;Korekcja dystorsji obiektywu +HISTORY_MSG_63;Zapamietaj wybrany +HISTORY_MSG_64;Kadrowanie zdjecia +HISTORY_MSG_65;Korekcja aberracji +HISTORY_MSG_66;Odzyskiwanie przeswietlen +HISTORY_MSG_67;Sila odzyskiwania przeswietlen +HISTORY_MSG_68;Metoda odzyskiwania Przeswietlen +HISTORY_MSG_69;Robocza przestrzen kolorow +HISTORY_MSG_70;Wyjsciowa przestrzen kolorow +HISTORY_MSG_71;Wejsciowa przestrzen kolorow +HISTORY_MSG_72;Korekcja winietowania +HISTORY_MSG_73;Mikser kanalow +HISTORY_MSG_74;Skala zmiany rozmiaru +HISTORY_MSG_75;Metoda zmiany rozmiaru +HISTORY_MSG_76;Metadane Exif +HISTORY_MSG_77;Metadane IPTC +HISTORY_MSG_78;Data specified for resize +HISTORY_MSG_79;Szerokosc skalowania +HISTORY_MSG_80;Wysokosc skalowania +HISTORY_MSG_81;Skalowanie wlaczone +HISTORY_MSG_82;Profil zmieniony +HISTORY_MSG_83;Wysokiej jakosci niedoswietlenia/przeswietlenia +HISTORY_MSG_84;Korekcja perspektywy +HISTORY_MSG_85;Wspolczynniki wavelet +HISTORY_MSG_86;Korektor wavelet +HISTORY_MSG_87;Impulsowa redukcja szumu +HISTORY_MSG_88;Prog impulsowej redukcji szumu +HISTORY_MSG_89;Redukcja szumu +HISTORY_MSG_90;NR - luminacja +HISTORY_MSG_91;NR - chrominacja +HISTORY_MSG_92;NR - gamma +HISTORY_MSG_93;Kontrast wg. poziomu wartosci detali +HISTORY_MSG_94;Kontrast wg. poziomu detali +HISTORY_MSG_95;Nasycenie +HISTORY_MSG_96;'a' krzywa +HISTORY_MSG_97;'b' krzywa +HISTORY_MSG_98;Algorytm demozaikowania +HISTORY_MSG_99;Filtrowania goracych/martwych pikseli +HISTORY_MSG_100;Nasycenie RGB +HISTORY_MSG_101;HSV EQ -- Odcien +HISTORY_MSG_102;HSV EQ -- Nasycenie +HISTORY_MSG_103;HSV EQ -- Mocy Swiatla Bialego +HISTORY_MSG_104;HSV korektor +HISTORY_MSG_105;Usuwanie widma +HISTORY_MSG_106;Promien dla usuwania widma +HISTORY_MSG_107;Prog dla usuwania widma +HISTORY_MSG_108;Prog kompresji przeswietlen +HISTORY_MSG_109;Wymiary obwodu +HISTORY_MSG_110;Skalowanie dotyczy +HISTORY_MSG_111;Unikaj przycinania koloru +HISTORY_MSG_112;Ogranicznik nasycenia +HISTORY_MSG_113;Ograniczenie nasyczenia +HISTORY_MSG_114;Liczba powtorzen DCB +HISTORY_MSG_115;Liczba powtorzen zapobiegania falszowaniu koloru +HISTORY_MSG_116;Rozszerzone DCB +HISTORY_MSG_117;Korekcja czerwonej aberracji chromatycznej +HISTORY_MSG_118;Korekcja niebieskiej aberracji chromatycznej +HISTORY_MSG_119;Odszumianie liniowe +HISTORY_MSG_120;Prog wyrownania zieleni +HISTORY_MSG_121;Autokorekta aberracji chromatycznej +HISTORY_MSG_122;Automatyczna czarna klatka +HISTORY_MSG_123;Plik czarnej klatki +HISTORY_MSG_124;Liniowa korekcja ekspozycji +HISTORY_MSG_125;Korekcja ekspozycji z zapobieganiem przeswietleniom +HISTORY_MSG_126;Plik pustego pola +HISTORY_MSG_127;Autowybor pustego pola +HISTORY_MSG_128;Promien rozmycia dla pustego pola +HISTORY_MSG_129;Typ rozmycia dla pustego pola +HISTORY_MSG_130;Automatyczna korekcja dystorsji +HISTORY_MSG_131;Redukcja szumu kanalu Luma +HISTORY_MSG_132;Redukcja szumu kanalu Chroma +HISTORY_MSG_133;Gamma +HISTORY_MSG_134;Pozycja gamma +HISTORY_MSG_135;Dowolna gamma +HISTORY_MSG_136;Nachylenie gamma +HISTORY_MSG_137;Czern - poziom zieleni 1 +HISTORY_MSG_138;Czern - poziom czerwieni +HISTORY_MSG_139;Czern - poziom niebieskiego +HISTORY_MSG_140;Czern - poziom zieleni 2 +HISTORY_MSG_141;Czern - poziom zielen 1+2 +HISTORY_MSG_142;Powtorzenia wyostrzania krawedzi +HISTORY_MSG_143;Sila wyostrzania krawedzi +HISTORY_MSG_144;Sila mikrokontrastu +HISTORY_MSG_145;Jednolitosc mikrokontrastu +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 - Odcienie pastelowe +HISTORY_MSG_153;Jaskrawosc - Odcienie nasycone +HISTORY_MSG_154;Jaskrawosc - Zachowaj odcienie skory +HISTORY_MSG_155;Jaskrawosc - Zapobiegaj zmianom kolorow +HISTORY_MSG_156;Jaskrawosc - Polacz odcienie pastelowe i nasycone +HISTORY_MSG_157;Jaskrawosc - Prog odcieni pastelowych/nasyconych +HISTORY_MSG_158;Sila +HISTORY_MSG_159;Wyszukanie krawedzi +HISTORY_MSG_160;Skala +HISTORY_MSG_161;Powtarzanie rozwazania +HISTORY_MSG_162;Tone Mapping +HISTORY_MSG_163;Krzywe RGB - R +HISTORY_MSG_164;Krzywe RGB - G +HISTORY_MSG_165;Krzywe RGB - B +HISTORY_MSG_166;Ustawienia neutralne +HISTORY_MSG_167;Tonacja B&W +HISTORY_MSG_168;Krzywa 'CC' +HISTORY_MSG_169;Krzywa 'CH' +HISTORY_MSG_170;Krzywa jaskrawosci +HISTORY_MSG_171;Krzywa 'LC' +HISTORY_MSG_172;Ogranicz LC do odcieni skory oraz czerwieni +HISTORY_MSG_173;NR - Szczegoly Luminancji +HISTORY_MSG_174;CIECAM02 +HISTORY_MSG_175;CAM02 - Sila adaptacji chrom. +HISTORY_MSG_176;CAM02 - Ciemnosc otoczenia widowni +HISTORY_MSG_177;CAM02 - Adaptacja luminancji sceny +HISTORY_MSG_178;CAM02 - Adaptacja luminancji widowni +HISTORY_MSG_179;CAM02 - Model +HISTORY_MSG_180;CAM02 - Jasnosc (J) +HISTORY_MSG_181;CAM02 - Chroma (C) +HISTORY_MSG_182;CAM02 - Automatyczne CAT02 +HISTORY_MSG_183;CAM02 - Kontrast (J) +HISTORY_MSG_184;CAM02 - Scena o ciemnym otoczeniu +HISTORY_MSG_185;CAM02 - Kontrola gamy +HISTORY_MSG_186;CAM02 - Algorytm +HISTORY_MSG_187;CAM02 - Ochrona odcieni skory i czerwieni +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 - Hue (kat) +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 - Pokaz wyjsciowy histogram CIECAM02 za krzywymi +HISTORY_MSG_200;CAMO2 - Tone mapping za pomoca CIECAM02 Q +HISTORY_MSG_201;NR - Roznica chrominancji czerwonych +HISTORY_MSG_202;NR - Roznica chrominancji niebieskich +HISTORY_MSG_203;NR - Metoda +HISTORY_MSG_204;Kroki poprawy LMMSE +HISTORY_MSG_205;CAM02 gorace/uszkodzone piksele +HISTORY_MSG_206;CAT02 - Automatyczna adaptacja do sceny +HISTORY_MSG_207;Krzywa usuwania widma +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_SAVEAS;Jako... +MAIN_BUTTON_SAVE;Zapisz obraz +MAIN_BUTTON_SAVE_TOOLTIP;Zapisz biezace zdjecieCtrl+S +MAIN_BUTTON_SENDTOEDITOR;Wyslij do edytora +MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Otworz biezace zdjecie w zewnetrznym edytorze Ctrl+E +MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Pokaz/Ukryj wszystkie panele boczne m +MAIN_BUTTON_UNFULLSCREEN;Zwolnij ekran +MAIN_FRAME_BATCHQUEUE;Kolejka +MAIN_FRAME_BATCHQUEUE_TOOLTIP;Przetwarzanie wsadowe Ctrl-F3 +MAIN_FRAME_EDITOR;Edytor +MAIN_FRAME_EDITOR_TOOLTIP; Edytor Ctrl-F4 +MAIN_FRAME_FILEBROWSER;Menedzer plikow +MAIN_FRAME_FILEBROWSER_TOOLTIP; Przegladanie plikow 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;Alt-c +MAIN_TAB_DETAIL;Szczegoly +MAIN_TAB_DETAIL_TOOLTIP;Alt-d +MAIN_TAB_DEVELOP; Przetwarzanie +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPORT; Eksport +MAIN_TAB_EXPOSURE;Ekspozycja +MAIN_TAB_EXPOSURE_TOOLTIP;Alt-e +MAIN_TAB_FILTER; Filter +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadane +MAIN_TAB_METADATA_TOOLTIP;Alt-m +MAIN_TAB_RAW;RAW +MAIN_TAB_RAW_TOOLTIP;Alt-r +MAIN_TAB_TAGGING;Tagowanie +MAIN_TAB_TRANSFORM;Transformacje +MAIN_TAB_TRANSFORM_TOOLTIP;Alt-t +MAIN_TOOLTIP_BACKCOLOR0;Kolor tla podgladu: Tematyczny\nSkrot: 8 +MAIN_TOOLTIP_BACKCOLOR1;Kolor tla podgladu: Czarny\nSkrot: 9 +MAIN_TOOLTIP_BACKCOLOR2;Kolor tla podgladu: Bialy\nSkrot: 0 +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, klawisz skrotu: H) +MAIN_TOOLTIP_INDCLIPPEDH;Pokaz przeswietlenia +MAIN_TOOLTIP_INDCLIPPEDS;Pokaz niedoswietlenia +MAIN_TOOLTIP_PREVIEWB;Podglad kanalu niebieskiego\nSkrot: b +MAIN_TOOLTIP_PREVIEWFOCUSMASK;Podglad maski ostrosci (beta)\nSkrot: Shift-F\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\n0.299*R + 0.587*G + 0.114*B\nSkrot: v +MAIN_TOOLTIP_PREVIEWR;Podglad kanalu czerwonego\nSkrot: r +MAIN_TOOLTIP_QINFO;Informacje o pliku +MAIN_TOOLTIP_SHOWHIDELP1;Pokaz/Ukryj lewy panel l +MAIN_TOOLTIP_SHOWHIDERP1;Pokaz/Ukryj prawy panel Alt-l +MAIN_TOOLTIP_SHOWHIDETP1;Pokaz/Ukryj gorny panel Shift-l +MAIN_TOOLTIP_THRESHOLD;Prog +MAIN_TOOLTIP_TOGGLE;Przelacz widok Przed/Po B +NAVIGATOR_B_NA;B = n/a +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_LAB_A_NA;A = n/a +NAVIGATOR_LAB_A_VALUE;A = %1 +NAVIGATOR_LAB_B_NA;B = n/a +NAVIGATOR_LAB_B_VALUE;B = %1 +NAVIGATOR_LAB_L_NA;L = n/a +NAVIGATOR_LAB_L_VALUE;L = %1 +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_V_VALUE;V = %1 +NAVIGATOR_XY_FULL;Szerokosc = %1, Wysokosc = %2 +NAVIGATOR_XY_NA;x = n/a, y = n/a +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 AbChr +PARTIALPASTE_CHANNELMIXER;Mikser kanalow +PARTIALPASTE_COARSETRANS;Rotacja/odwrocenie o 90 stopni +PARTIALPASTE_COLORAPP;CIE Color Appearance Model 2002 +PARTIALPASTE_COLORGROUP;Ustawienia zwiazane z kolorem +PARTIALPASTE_COMMONTRANSFORMPARAMS;Autouzupelnienie +PARTIALPASTE_COMPOSITIONGROUP;Ustawienia kompozycji +PARTIALPASTE_CROP;Przytnij +PARTIALPASTE_DARKFRAMEAUTOSELECT;Auto wybor czarnej klatki +PARTIALPASTE_DARKFRAMEFILE;Plik 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;Zmien dane Exif +PARTIALPASTE_EXPOSURE;Ekspozycja +PARTIALPASTE_FLATFIELDAUTOSELECT;FF autowybor +PARTIALPASTE_FLATFIELDBLURRADIUS;FF promien rozmycia +PARTIALPASTE_FLATFIELDBLURTYPE;FF typ rozmycia +PARTIALPASTE_FLATFIELDFILE;Plik pustego pola (FF) +PARTIALPASTE_HSVEQUALIZER;Korektor HSV +PARTIALPASTE_ICMGAMMA;Gamma wyjsciowa +PARTIALPASTE_ICMSETTINGS;Ustawienia ICM +PARTIALPASTE_IMPULSEDENOISE;Impulsowa redukcja szumu +PARTIALPASTE_IPTCINFO;Informacje IPTC +PARTIALPASTE_LABCURVE;Regulacje Lab +PARTIALPASTE_LENSGROUP;Ustawienia zwiazane z obiektywem +PARTIALPASTE_LENSPROFILE;Profil korekcji obiektywu LCP +PARTIALPASTE_LUMACURVE;Krzywa obiektywu +PARTIALPASTE_METAICMGROUP;Metadane/Ustawienia ICM +PARTIALPASTE_PERSPECTIVE;Perspektywa +PARTIALPASTE_PREPROCESS_GREENEQUIL;Wyrownanie zieleni +PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Usun gorace/uszkodzone (swiece) piksele +PARTIALPASTE_PREPROCESS_LINEDENOISE;Liniowa redukcja szumu +PARTIALPASTE_RAWCACORR_AUTO;Autokorekta aberracji chromatycznej +PARTIALPASTE_RAWCACORR_CABLUE;AbChr niebieski +PARTIALPASTE_RAWCACORR_CARED;AbChr czerwony +PARTIALPASTE_RAWEXPOS_BLACK;Poziom czerni +PARTIALPASTE_RAWEXPOS_LINEAR;Wspolczynnik liniowej korekcji bieli RAW +PARTIALPASTE_RAWEXPOS_PRESER;Czujnik przeswietlania bieli RAW (EV) +PARTIALPASTE_RAWGROUP;Ustawienia RAW +PARTIALPASTE_RAW_ALLENHANCE;Zastosuj redukcje szumu i artefaktow po demozaikowaniu +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;Zmien rozmiar +PARTIALPASTE_RGBCURVES;Krzywe RGB +PARTIALPASTE_ROTATION;Rotacja +PARTIALPASTE_SHADOWSHIGHLIGHTS;Cienie/Swiatla +PARTIALPASTE_SHARPENEDGE;Krawedzie +PARTIALPASTE_SHARPENING;Wyostrzanie +PARTIALPASTE_SHARPENMICRO;Mikrokontrast +PARTIALPASTE_VIBRANCE;Jaskrawosc +PARTIALPASTE_VIGNETTING;Korekcja winiety +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_BLINKCLIPPED;Mrugajace przeswietlenia +PREFERENCES_CACHECLEARALL;Wyczysc wszystko +PREFERENCES_CACHECLEARPROFILES;Wyczysc profile +PREFERENCES_CACHECLEARTHUMBS;Wyczysc miniaturki +PREFERENCES_CACHEFORMAT1;Wlasnosciwe (szybciej i z lepsza jakoscia) +PREFERENCES_CACHEFORMAT2;JPEG (mniejsze zuzycie dysku) +PREFERENCES_CACHEMAXENTRIES;Maksymalna liczba wpisow w pamieci podrecznej +PREFERENCES_CACHEOPTS;Opcje pamieci podrecznej +PREFERENCES_CACHETHUMBFORM;Format miniatur w 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_CLEARDLG_LINE1;Czyszczenie pamieci podrecznej +PREFERENCES_CLEARDLG_LINE2;Moze to potrwac kilka sekund. +PREFERENCES_CLEARDLG_TITLE;Prosze czekac +PREFERENCES_CLIPPINGIND;Pokazywanie przeswietlen +PREFERENCES_CMETRICINTENT;Sposob odwzorowania barw +PREFERENCES_CUSTPROFBUILDHINT;Plik wykonywalny (lub skrypt) uruchamiany w celu wygenerowania profilu poczatkowego dla zdjecia.\nOtrzymuje nastepujace parametry linii polecen przydatne do wygenerowania pliku .pp3 :\n[Path RAW/JPG] [Path default profile] [f-no] [exposure in secs] [focal length in mm] [ISO] [Lens] [Camera] +PREFERENCES_CUSTPROFBUILDPATH;Sciezka pliku wykonywalnego +PREFERENCES_CUSTPROFBUILD;Zewnetrzny kreator profilu dla zdjecia +PREFERENCES_CUTOVERLAYBRUSH;Maska koloru/przezroczystosci +PREFERENCES_D50;5000K +PREFERENCES_D55;5500K +PREFERENCES_D60;6000K +PREFERENCES_D65;6500K +PREFERENCES_DARKFRAMEFOUND;Znaleziono +PREFERENCES_DARKFRAMESHOTS;kadry +PREFERENCES_DARKFRAMETEMPLATES;szablony +PREFERENCES_DARKFRAME;Czarna klatka +PREFERENCES_DATEFORMATFRAME;Format daty +PREFERENCES_DATEFORMATHINT;Dozwolone sa nastepujace kody formatujace:\n%y : year\n%m : miesiac\n%d : dzien\n\nPrzykladowy wegierski format daty to:\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_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_GTKTHEME;Domyslny temat GTK +PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogram w lewym panelu +PREFERENCES_HLTHRESHOLD;Prog dla przeswietlen +PREFERENCES_ICCDIR;Katalog z profilami 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 raw, jesli nieedytowany +PREFERENCES_LANGAUTODETECT;Uzycie systemowych ustawien jezykowych +PREFERENCES_MENUGROUPEXTPROGS;Grupuj "Otworz za pomoca" +PREFERENCES_MENUGROUPFILEOPERATIONS;Grupuj operacje plikow +PREFERENCES_MENUGROUPLABEL;Grupuj operacje etykiet +PREFERENCES_MENUGROUPPROFILEOPERATIONS;Grupuj operacje profili +PREFERENCES_MENUGROUPRANK;Grupuj operacje oceny +PREFERENCES_MENUOPTIONS;Opcje menu +PREFERENCES_METADATA;Metadane +PREFERENCES_MONITORICC;Profil monitora +PREFERENCES_MULTITABDUALMON;Tryb wielu zakladek, jezeli dostepny drugi monitor +PREFERENCES_MULTITAB;Tryb wielu zakladek +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, ...\n\nKody formatujace odnosza sie do katalogow i podkatalogow w sciezce pliku raw.\n\nPrzykladowo, jezeli otworzono plik /home/tom/image/02-09-2006/dsc0012.nef, znaczenie kodow formatujacych bedzie nastepujace:\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\nBy zapisac plik wyjsciowy obok pliku orginalnego, prosze wpisac:\n%p1/%f\n\nJezeli zdjecia maja zostac umieszczone w nowym katalog 'converted' znajdujacym sie w katalogu zrodlowym, prosze wpisac:\n%p1/converted/%f\n\nJezeli zdjecia maja zostac umieszczone w katalogu '/home/tom/converted' zgrupowane w podkatalogi z data w nazwie, prosze wpisac:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Uzyj schemat +PREFERENCES_OUTDIR;Katalog wyjsciowy +PREFERENCES_OVERLAY_FILENAMES;Nakladaj nazwy pliku na miniatury +PREFERENCES_OVERWRITEOUTPUTFILE;Nadpisuj istniejace pliki +PREFERENCES_PANFACTORFRAME;Przyspieszenie podczas przesuwania podgladu +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 Usuwania Szumow +PREFERENCES_RGBDTL_TOOLTIP;Usuwanie Szumow potrzebuje 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_SHOWPROFILESELECTOR;Umozliw wybor profilu +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 Window nalezy stosowac "SystemDefault", "SystemAsterisk" itp. dla dzwiekow systemowych. +PREFERENCES_SND_LNGEDITPROCDONE;Praca edytora wykonana +PREFERENCES_SND_TRESHOLDSECS;po sekundach +PREFERENCES_SQUAREDETAILWINDOW;Mniejsze okno lupy (szybsze) +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_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_FILEDLGFILTERANY;Wszystkie pliki +PROFILEPANEL_FILEDLGFILTERPP;Profile przetwarzania koncowego +PROFILEPANEL_LABEL;Profil przetwarzania koncowego +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 RT.\n\nWylaczone: profile zostana zastosowane takie, jakie sa, zmieniajac tylko te wartosci, ktore zawieraja. +PROFILEPANEL_PASTEPPASTE;Parametry do wklejenia +PROFILEPANEL_PCUSTOM;Reczny +PROFILEPANEL_PFILE;Z pliku +PROFILEPANEL_PLASTSAVED;Ostatnio zapisany +PROFILEPANEL_SAVEDLGLABEL;Zapisz parametry przetwarzania koncowego... +PROFILEPANEL_SAVEPPASTE;Parametry do zapisania +PROFILEPANEL_TOOLTIPCOPY;Skopiuj aktualny profil do schowka +PROFILEPANEL_TOOLTIPLOAD;Laduj profil z pliku +PROFILEPANEL_TOOLTIPPASTE;Wklej profil ze schowka +PROFILEPANEL_TOOLTIPSAVE;Zapisz aktualny profil +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 parametry 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_LOADING;Wczytywanie pliku... +PROGRESSDLG_PROCESSING;Przetwarzanie zdjecia... +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profil zmieniony w przegladarce +PROGRESSDLG_SAVING;Zapisywanie pliku... +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_JPGFILTER;Pliki 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_TIFFFILTER;Pliki TIFF +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 (klawisz skrotu: C) +TOOLBAR_TOOLTIP_HAND;Przesun (klawisz skrotu: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Wyprostuj obraz (klawisz skrotu: S) +TOOLBAR_TOOLTIP_WB;Wskaz balans bieli (klawisz skrotu: W) +TP_CACORRECTION_BLUE;Niebieski +TP_CACORRECTION_LABEL;Korekcja aberracji +TP_CACORRECTION_RED;Czerwony +TP_CHMIXER_BLUE;Niebieski +TP_CHMIXER_GREEN;Zielony +TP_CHMIXER_LABEL;Mikser kanalow +TP_CHMIXER_RED;Czerwony +TP_CHROMATABERR_LABEL;Aberracja chromatyczna +TP_COARSETRAF_DEGREE;stopnie: +TP_COARSETRAF_TOOLTIP_HFLIP;Odbij w poziomie +TP_COARSETRAF_TOOLTIP_ROTLEFT;Obroc w lewo +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Obroc w prawo +TP_COARSETRAF_TOOLTIP_VFLIP;Odbij w pionie +TP_COLORAPP_ADAPTSCENE;Adaptacja luminancji sceny +TP_COLORAPP_ADAPTSCENE_TOOLTIP;Bezwzgledna luminancja sceny (cd/m²).\n 1)Obliczona za pomoca Exif:\nCzas naswietlania - ISO - Apertura - Korekta ekspozycji EV.\n2)Obliczona rowniez na podstawie punktu bieli raw oraz korekty ekspozycji w RT +TP_COLORAPP_ADAPTVIEWING;Adaptacja luminancji widowni (cd/m²) +TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Bezwzgledna luminancja widowni\n(zazwyczaj 16cd/m²) +TP_COLORAPP_ADAP_AUTO_TOOLTIP;Jesli zaznaczone (polecamy), RT 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;Jasnosc + Chroma (JC) +TP_COLORAPP_ALGO_JS;Jasnosc + 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 1=mediana 2=gaussa.\n\nTe anomalie wynikaja z limitacji CIECAM02. Mozna rowniez dostroic obraz aby uniknac bardzo ciemnych miejsc. +TP_COLORAPP_BRIGHT;Jasnosc (Q) +TP_COLORAPP_BRIGHT_TOOLTIP;Jasnosc w CIECAM02 bierze pod uwage luminancje bieli i rozni sie od jasnosci Lab 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 Lab oraz RGB. +TP_COLORAPP_CHROMA_S;Nasycenie (S) +TP_COLORAPP_CHROMA_S_TOOLTIP;Nasycenie w CIECAM02 rozni sie od nasycenia Lab oraz RGB. +TP_COLORAPP_CHROMA_TOOLTIP;Chroma w CIECAM02 rozni sie od chromy Lab 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 Lab oraz RGB. +TP_COLORAPP_CONTRAST_TOOLTIP;Kontrast w CIECAM02 dla suwaka J, rozni sie od kontrastu Lab oraz RGB. +TP_COLORAPP_CURVEEDITOR1;Krzywa tonalna 1 +TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Pokazuje histogram L (Lab) 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 (Lab) przed CIECAM02.\nJesli opcja "Pokaz histogramy wyjsciowe CIECAM02 za krzywymi" jest wlaczona, pokazuje histogram C, s oraz 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 korektach CIECAM02.\nTen wybor nie ma wplywu glownego histogramu.\n\nKiedy opcja jest wylaczona, histogramy za krzywymi CIECAM02 pokazuja wartosci Lab przed korektami CIECAM02. +TP_COLORAPP_DEGREE_AUTO_TOOLTIP;Jesli opcja jest zaznaczona (zalecane), RT kalkuluje wartosc optymalna, ktora jest potem uzyta przez CAT02 oraz przez cale CIECAM02.\nAby ustawic wartosc recznie, odznacz opcje (wartosci powyzej 65 zalecane) +TP_COLORAPP_DEGREE_TOOLTIP;Sila CIE Chromatic Adaptation Transform 2002 +TP_COLORAPP_GAMUT;Kontrola gamy (Lab) +TP_COLORAPP_GAMUT_TOOLTIP;Wlacz kontrole gamy w trybie Lab +TP_COLORAPP_HUE;Hue (h) +TP_COLORAPP_HUE_TOOLTIP;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 Lab oraz RGB +TP_COLORAPP_MODEL;Model punktu bieli (WB) +TP_COLORAPP_MODEL_TOOLTIP;WB [RT] + [wyjsciowy]:\nBalans bieli RT jest uzyty dla sceny, CIECAM02 jest ustawione na D50, balans bieli urzadzenia wyjsciowego ustawiony jest w Ustawieniach > Zarzadzanie Kolorami\n\nWB [RT+CAT02] + [wyjsciowe]:\nUstawienia balansu bieli RT sa uzywane przez CAT02, i balans bieli urzadzenia wyjsciowego jest ustawione w Ustawieniach. +TP_COLORAPP_RSTPRO;Ochrona odcieni skory i czerwieni +TP_COLORAPP_RSTPRO_TOOLTIP;Ochrona odcieni skory i czerwieni (suwaki i krzywe) +TP_COLORAPP_SHARPCIE;Wyostrzanie, Kontrast wg. Poziomu Detali, Mikrokontrast & Usuwanie Widma za pomoca Q/C +TP_COLORAPP_SHARPCIE_TOOLTIP;Wyostrzanie, Kontrast wg. Poziomu Detali, Mikrokontrast & Usuwanie Widma wykorzystaja CIECAM02 jesli wlaczone. +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)\nObraz sie nie zmieni.\n\nPrzycmione:\nPrzycmione otoczenie (TV)\nObraz stanie sie troszke ciemniejszy.\n\nCiemne:\nCiemne otoczenie (projektor)\nObraz stanie sie jeszcze ciemniejszy.\n\nBardzo Ciemne:\nBardzo ciemne otoczenie (cut-sheet)\nObraz 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 Lab, zas jesli jest wlaczona, w przestrzeni kolorow CIECAM02.\nNarzedzie Tone Mapping musi byc wlaczone aby to utawienie dzialalo. +TP_COLORAPP_WBCAM;WB [RT+CAT02] + [wyjsciowy] +TP_COLORAPP_WBRT;WB [RT] + [wyjsciowy] +TP_COLORBOOST_ACHANNEL;kanal "a" +TP_COLORBOOST_AMOUNT;Stopien +TP_COLORBOOST_AVOIDCOLORCLIP;Unikaj przycinania kolorow +TP_COLORBOOST_BCHANNEL;kanal "b" +TP_COLORBOOST_CHANNEL;Kanal +TP_COLORBOOST_CHSEPARATE;oddzielnie +TP_COLORBOOST_ENABLESATLIMITER;Limit nasycenia +TP_COLORBOOST_LABEL;Wzmocnienie koloru +TP_COLORBOOST_SATLIMIT;Limit nasycenia +TP_COLORDENOISE_EDGESENSITIVE;Czulosc krawedzi +TP_COLORDENOISE_EDGETOLERANCE;Tolerancja krawedzi +TP_COLORDENOISE_LABEL;Odszumianie koloru +TP_COLORDENOISE_RADIUS;Promien +TP_COLORSHIFT_BLUEYELLOW;Blekit-zolty +TP_COLORSHIFT_GREENMAGENTA;Zielen-magenta +TP_COLORSHIFT_LABEL;Przesuniecie koloru +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;Zablokuj proporcje: +TP_CROP_GTDIAGONALS;Przekatna +TP_CROP_GTEPASSPORT;Paszport biometryczny +TP_CROP_GTFRAME;Ramka +TP_CROP_GTGRID;Siatka +TP_CROP_GTHARMMEANS1;Zloty podzial 1 +TP_CROP_GTHARMMEANS2;Zloty podzial 2 +TP_CROP_GTHARMMEANS3;Zloty podzial 3 +TP_CROP_GTHARMMEANS4;Zloty podzial 4 +TP_CROP_GTNONE;Nic +TP_CROP_GTRULETHIRDS;Trojpodzial +TP_CROP_GUIDETYPE;Typ pomocy: +TP_CROP_H;W +TP_CROP_LABEL;Kadrowanie +TP_CROP_PPI;PPI= +TP_CROP_SELECTCROP;Wybierz kadr +TP_CROP_W;S +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_DETAIL_AMOUNT;Sila +TP_DIRPYRDENOISE_BLUE;Roznica chrominancji niebieskich +TP_DIRPYRDENOISE_CHROMA;Chrominacja +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_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_LDETAIL;Szczegolowosc Luminancji +TP_DIRPYRDENOISE_LUMA;Luminacja +TP_DIRPYRDENOISE_METHOD;Metoda +TP_DIRPYRDENOISE_METHOD_TOOLTIP;Dla obrazow raw mozna uzywac metody RGB oraz Lab.\n\nDla obrazow nie-raw metoda Lab zostanie uzyta niezaleznie od wyboru. +TP_DIRPYRDENOISE_PERF;Tryb RGB (obrazy raw) +TP_DIRPYRDENOISE_RED;Roznica chrominancji czerwonych +TP_DIRPYRDENOISE_RGB;RGB +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_THRESHOLD;Prog +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 Lab (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_EQUALIZER_CONTRAST_MINUS;Kontrast- +TP_EQUALIZER_CONTRAST_PLUS;Kontrast+ +TP_EQUALIZER_FINEST;delikatnie +TP_EQUALIZER_LABEL;Korektor Wavelet +TP_EQUALIZER_LARGEST;zgrubnie +TP_EQUALIZER_NEUTRAL;Neutralne +TP_EXPOSCORR_LABEL;Punkt bieli raw +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 swiatel +TP_EXPOSURE_COMPRHIGHLIGHTS;Kompresja swiatel +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;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_EXPO_AFTER; Po interpolacji (przed konwersja RGB) +TP_FLATFIELD_AUTOSELECT;Autowybor +TP_FLATFIELD_BLURRADIUS;Promien rozmycia +TP_FLATFIELD_BLURTYPE;Typ rozmycia +TP_FLATFIELD_BT_AREA;Obszar +TP_FLATFIELD_BT_HORIZONTAL;Poziome +TP_FLATFIELD_BT_VERTHORIZ;Poz. + Pion. +TP_FLATFIELD_BT_VERTICAL;Pionowe +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_HLREC_BLEND;Mieszanie +TP_HLREC_CIELAB;Mieszanie koloru CIELab +TP_HLREC_COLOR;Propagacja koloru +TP_HLREC_LABEL;Odzyskiwanie przeswietlen +TP_HLREC_LUMINANCE;Odzyskiwanie luminancji +TP_HLREC_METHOD;Metoda: +TP_HSVEQUALIZER1;Czerwony +TP_HSVEQUALIZER2;Zolty +TP_HSVEQUALIZER3;Limonka +TP_HSVEQUALIZER4;Zielony +TP_HSVEQUALIZER5;Cyjan +TP_HSVEQUALIZER6;Niebieski +TP_HSVEQUALIZER7;Purpurowy +TP_HSVEQUALIZER8;Magenta +TP_HSVEQUALIZER_CHANNEL;Kanal HSV +TP_HSVEQUALIZER_HUE;H +TP_HSVEQUALIZER_LABEL;Korektor 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_FILEDLGFILTERANY;Wszystkie pliki +TP_ICM_FILEDLGFILTERICM;Pliki z profilami ICC +TP_ICM_GAMMABEFOREINPUT;Profil stosuje korekcje gamma +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;Reczny +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;No ICM: Wyjscie sRGB +TP_ICM_OUTPUTPROFILE;Profil wyjsciowy +TP_ICM_PREFERREDPROFILE;Preferowany profil DCP +TP_ICM_PREFERREDPROFILE_1;Swiatlo dzienne +TP_ICM_PREFERREDPROFILE_2;Wolfram +TP_ICM_PREFERREDPROFILE_3;Jarzeniowe +TP_ICM_PREFERREDPROFILE_4;Flash +TP_ICM_SAVEREFERENCE;Zapisz obraz wzorcowy dla profilowania +TP_ICM_TONECURVE;Uzyj krzywa tonalna z DCP +TP_ICM_TONECURVE_TOOLTIP;Wlacz aby umozliwic uzycie krzywej tonalnej ktora moze sie znajdowac w profilu DCP. +TP_ICM_WORKINGPROFILE;Profil roboczy +TP_IMPULSEDENOISE_LABEL;Impulsowa redukcja szumu +TP_IMPULSEDENOISE_THRESH;Prog impulsowej redukcji szumu +TP_LABCURVE_AVOIDCOLORCLIP;Unikaj przycinania koloru +TP_LABCURVE_AVOIDCOLORSHIFT;Unikaj zmian koloru +TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Umieszcza kolory w gamie roboczej przestrzeni kolorow i stosuje korekte Munsell'a +TP_LABCURVE_BRIGHTNESS;Jasnosc +TP_LABCURVE_BWTONING;Tonowanie B&W +TP_LABCURVE_BWTONING_TIP;Kiedy opcja jest wlaczona, Chromatycznosc Lab oraz krzywe CC, CH i LC nie maja wplywu na obraz.\nTonowanie mozna wykonac poprzez zmiane krzywych a oraz b. +TP_LABCURVE_CHROMATICITY;Chromatycznosc +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 C=f(C).\n\nPokazuje histogram chromatycznosci przed korekta krzywych.\nEfekt koncowy jest przedstawiony w glownym histogramie. +TP_LABCURVE_CURVEEDITOR_CH;CH +TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromatycznosc wedlug odcieni +TP_LABCURVE_CURVEEDITOR_LC;LC +TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminancja wedlug chromatycznosci +TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminancja Lab L=f(L).\n\nPokauje histogram L przed korekta krzywych.\nEfekt koncowy jest przedstawiony w glownym histogramie. +TP_LABCURVE_ENABLESATLIMITER;Limitowanie nasycenia +TP_LABCURVE_LABEL;Regulacja Lab +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_LABCURVE_SATLIMIT;Limit nasycenia +TP_LABCURVE_SATURATION;Nasycenie +TP_LENSGEOM_AUTOCROP;Auto przycinanie +TP_LENSGEOM_FILL;Auto wypelnienie +TP_LENSGEOM_LABEL;Obiektywy / Geometria +TP_LENSPROFILE_FILEDLGFILTERLCP;Profile korekcji obiektywow LCP +TP_LENSPROFILE_LABEL;Profil korekcji obiektywu LCP +TP_LENSPROFILE_USECA;Korekja aberacji chromatycznej +TP_LENSPROFILE_USEDIST;Korekcja dystorsji +TP_LENSPROFILE_USEVIGN;Korekcja winietowania +TP_LUMACURVE_BLACKLEVEL;Czern +TP_LUMACURVE_BRIGHTNESS;Jasnosc +TP_LUMACURVE_COMPRHIGHLIGHTS;Kompresja swiatel +TP_LUMACURVE_COMPRSHADOWS;Kompresja cieni +TP_LUMACURVE_CONTRAST;Kontrast +TP_LUMACURVE_CURVEEDITOR;Krzywa luminancji +TP_LUMACURVE_LABEL;Krzywa luminancji +TP_NEUTRAL;Neutralne +TP_NEUTRAL_TIP;Zresetuj ustawienia do wartosci neutralnych +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. Wyzej = bardziej, nizej = mniej. +TP_PREPROCESS_GREENEQUIL;Wyrownanie zieleni +TP_PREPROCESS_HOTDEADPIXFILT;Usun gorace/uszkodzone (swiece) piksele +TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Usun gorace/uszkodzone (swiece) piksele +TP_PREPROCESS_HOTDEADPIXTHRESH;Prog wykrycia goracych/martwych pikseli +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_BLACKONE;Czern: poziom czerwieni +TP_RAWEXPOS_BLACKS;Poziomy czerni +TP_RAWEXPOS_BLACKTHREE;Czern: poziom zieleni 2 +TP_RAWEXPOS_BLACKTWO;Czern: poziom niebieskiego +TP_RAWEXPOS_BLACKZERO;Czern: poziom zieleni 1 (glowny) +TP_RAWEXPOS_LINEAR;Liniowy wspolczynnik korekcji +TP_RAWEXPOS_PRESER;Czujnik przeswietlenia bieli (EV) +TP_RAWEXPOS_TWOGREEN;Polacz obie zielenie +TP_RAW_ALLENHANCE;Reducja szumu i artefaktow po demozaikowaniu +TP_RAW_DCBENHANCE;Zastosuj poprawe DCB +TP_RAW_DCBITERATIONS;Liczba powtorzen DCB +TP_RAW_DMETHOD;Metoda +TP_RAW_DMETHOD_PROGRESSBAR;Demosaicowanie %1... +TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Udoskonalanie demosaicowania... +TP_RAW_DMETHOD_TOOLTIP;IGV oraz LMMSE sa przeznaczone dla zdjec raw o wysokim poziomie szumow (wysokie ISO). +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_RESIZE_APPLIESTO;Dotyczy: +TP_RESIZE_BICUBICSF;Bicubic (Miekko) +TP_RESIZE_BICUBICSH;Bicubic (Ostro) +TP_RESIZE_BICUBIC;Bicubic +TP_RESIZE_BILINEAR;Bilinear +TP_RESIZE_CROPPEDAREA;Obszaru przyciecia +TP_RESIZE_DOWNSCALEB;Downscale (Dokladniej) +TP_RESIZE_DOWNSCALEF;Downscale (Szybciej) +TP_RESIZE_FITBOX;Wymiary obwodu +TP_RESIZE_FULLIMAGE;Calego zdjecia +TP_RESIZE_HEIGHT;Wysokosc +TP_RESIZE_H;W: +TP_RESIZE_LABEL;Skalowanie +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;S: +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_AUTOCROP;Auto przycinanie +TP_ROTATE_DEGREE;Stopnie +TP_ROTATE_FILL;Wypelnij +TP_ROTATE_LABEL;Obrot +TP_ROTATE_SELECTLINE;Wyprostuj obraz +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Swiatla +TP_SHADOWSHLIGHTS_HLTONALW;Szerokosc tonalna +TP_SHADOWSHLIGHTS_LABEL;Cienie/Swiatla +TP_SHADOWSHLIGHTS_LOCALCONTR;Kontrast lokalny +TP_SHADOWSHLIGHTS_RADIUS;Promien +TP_SHADOWSHLIGHTS_SHADOWS;Cienie +TP_SHADOWSHLIGHTS_SHTONALW;Szerokosc tonalna +TP_SHARPENEDGE_AMOUNT;Sila +TP_SHARPENEDGE_LABEL;Krawedzie +TP_SHARPENEDGE_PASSES;Powtorzenia +TP_SHARPENEDGE_THREE;Tylko luminacja +TP_SHARPENING_AMOUNT;Sila +TP_SHARPENING_EDRADIUS;Promien +TP_SHARPENING_EDTOLERANCE;Tolerancja +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;Barwy 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 wedlug odcieni +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 barwy pastelowe na dole oraz nasycone 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;Centrum +TP_VIGNETTING_CENTER_X;Centrum X +TP_VIGNETTING_CENTER_Y;Centrum 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;Reczny +TP_WBALANCE_DAYLIGHT;Swiatlo dzienne (slonecznie) +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 +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;Otworz (nowa) lupe +ZOOMPANEL_ZOOM100;Powieksz do 100%\nSkrot: z +ZOOMPANEL_ZOOMFITSCREEN;Dopasuj do ekranu\nSkrot: f +ZOOMPANEL_ZOOMIN;Przybliz\nSkrot: + +ZOOMPANEL_ZOOMOUT;Oddal\nSkrot: - + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!FILEBROWSER_POPUPRANK;Rank +!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;'CL' curve +!HISTORY_MSG_247;'LH' curve +!HISTORY_MSG_248;'HH' curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!PARTIALPASTE_CHANNELMIXERBW;Black-and-White +!PARTIALPASTE_GRADIENT;Graduated filter +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PREFERENCES_CUSTPROFBUILDKEYFORMAT;Keys format +!PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Name +!PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID +!PREFERENCES_USEBUNDLEDPROFILES;Use bundled profiles +!PROFILEPANEL_GLOBALPROFILES;Bundled profiles +!PROFILEPANEL_MYPROFILES;My profiles +!PROFILEPANEL_PINTERNAL;Neutral +!TP_BWMIX_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing channel-mixer +!TP_BWMIX_BLUE;Blue +!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;Modify luminance in function of hue\nPay attention to extreme values that may cause artifacts +!TP_BWMIX_CYAN;Cyan +!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 simulate shots taken with a colored filter placed in front of the lens. Colored filters reduce transmission of specific range of colors and correspondingly affect their lightness. E.g. a Red filter darkens Blue skies. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_BLUE;Blue Channel +!TP_BWMIX_GAM_GREEN;Green Channel +!TP_BWMIX_GAM_RED;Red Channel +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each channel RGB +!TP_BWMIX_GREEN;Green +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MAGENTA;Magenta +!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 (filter, channel-mixer) to default +!TP_BWMIX_ORANGE;Orange +!TP_BWMIX_PURPLE;Purple +!TP_BWMIX_RED;Red +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all of the mixer options\nTotal displays the sum of RGB values actually applied:\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 (films, landscape, ...) or manual settings of channel-mixer +!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;Channel-Mixer absolute RGB +!TP_BWMIX_SET_RGBREL;Channel-Mixer relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Channel-Mixer absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Channel-Mixer 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_BWMIX_YELLOW;Yellow +!TP_DIRPYRDENOISE_ENH;Enhanced mode +!TP_DIRPYRDENOISE_ENH_TOOLTIP;Increases noise reduction quality at the expense of a 20% processing time increase +!TP_GENERAL_11SCALE_TOOLTIP;The effect of this tool or some of its sub-component is only visible at 1:1 preview scale. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Rotation anchor point X: -100=left edge, 0=center, +100=right edge +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Rotation anchor point Y: -100=top edge, 0=center, +100=bottom edge +!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 automatic exposure +!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_TOOLTIP;Save the linear TIFF image before the input profile is applied. Result can be used for calibration purposes, 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_PCVIGNETTE_FEATHER;Feather +!TP_PCVIGNETTE_FEATHER_TOOLTIP;Feathering: 0=corners only, 50=halfway to center, 100=to center +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness: 0=rectangle, 50=fitted ellipse, 100=circle +!TP_PCVIGNETTE_STRENGTH;Strength +!TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filter strength in stops (reached in corners) +!TP_SAVEDIALOG_OK_TIP;Shortcut Ctrl-Enter +!TP_SHADOWSHLIGHTS_SHARPMASK;Sharp mask +!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 diff --git a/rtdata/languages/Portugues (Brasil) b/rtdata/languages/Portugues (Brasil) new file mode 100644 index 000000000..007c448e9 --- /dev/null +++ b/rtdata/languages/Portugues (Brasil) @@ -0,0 +1,1441 @@ +#01 2010-02-01 Vitor da Silva Gonçalves + +ADJUSTER_RESET_TO_DEFAULT;Restaurar para o padrão +CURVEEDITOR_FILEDLGFILTERANY;Quaisquer Arquivos +CURVEEDITOR_FILEDLGFILTERCURVE;Arquivos de curva +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 +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_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_SAVEAS;Como... +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_TAGGING;Tagging +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_LUMACURVE;Curva de luminância +PARTIALPASTE_METAICMGROUP;Metadados/configurações ICM +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_BLINKCLIPPED;Piscar áreas recortadas +PREFERENCES_CACHECLEARALL;Limpar Tudo +PREFERENCES_CACHECLEARPROFILES;Limpar perfis +PREFERENCES_CACHECLEARTHUMBS;Limpar Miniaturas +PREFERENCES_CACHEFORMAT1;Proprietário (mais rápido e melhor qualidade) +PREFERENCES_CACHEFORMAT2;JPEG (Menor espaço em disco) +PREFERENCES_CACHEMAXENTRIES;Número máximo de entradas no cache +PREFERENCES_CACHEOPTS;Opções de Cache +PREFERENCES_CACHETHUMBFORM;Formato das miniaturas no cache +PREFERENCES_CACHETHUMBHEIGHT;Tamanho máximo das miniaturas +PREFERENCES_CLEARDLG_LINE1;Limpando cache +PREFERENCES_CLEARDLG_LINE2;Isto pode levar alguns segundos. +PREFERENCES_CLEARDLG_TITLE;Por favor aguarde +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_GTKTHEME;Padrão do GTK +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_FILEDLGFILTERANY;Quaisquer arquivos +PROFILEPANEL_FILEDLGFILTERPP;Perfis de pós-processamento +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... +PROGRESSDLG_LOADING;Carregando arquivo... +PROGRESSDLG_PROCESSING;Processando imagem... +PROGRESSDLG_SAVING;Salvando arquivo... +QINFO_ISO;ISO +QINFO_NOEXIF;Dados Exif não disponíveis. +SAVEDLG_FILEFORMAT;Formato do Arquivo +SAVEDLG_JPEGQUAL;Qualidade do JPEG +SAVEDLG_JPGFILTER;Arquivos 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 +SAVEDLG_TIFFFILTER;Arquivos TIFF +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_DEGREE;graus: +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_COLORBOOST_ACHANNEL;Canal "a" +TP_COLORBOOST_AMOUNT;Quantidade +TP_COLORBOOST_AVOIDCOLORCLIP;Evitar clipping de cor +TP_COLORBOOST_BCHANNEL;Canal "b" +TP_COLORBOOST_CHANNEL;Canal +TP_COLORBOOST_CHSEPARATE;separar +TP_COLORBOOST_ENABLESATLIMITER;Habilitar limite de saturação +TP_COLORBOOST_LABEL;Melhoria de Cor +TP_COLORBOOST_SATLIMIT;Limite de Saturação +TP_COLORDENOISE_EDGESENSITIVE;Sensitivo a bordas +TP_COLORDENOISE_EDGETOLERANCE;Tolerância de bordas +TP_COLORDENOISE_LABEL;Redução de Ruidos da Cor +TP_COLORDENOISE_RADIUS;Raio +TP_COLORSHIFT_BLUEYELLOW;Azul-Amarelo +TP_COLORSHIFT_GREENMAGENTA;Verde-Magenta +TP_COLORSHIFT_LABEL;Alternância de cor +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;Relação Fixa: +TP_CROP_GTDIAGONALS;Regra das diagonais +TP_CROP_GTHARMMEANS1;Harmonico 1 +TP_CROP_GTHARMMEANS2;Harmonico 2 +TP_CROP_GTHARMMEANS3;Harmonico 3 +TP_CROP_GTHARMMEANS4;Harmonico 4 +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_FILEDLGFILTERANY;Quaisquer Arquivos +TP_ICM_FILEDLGFILTERICM;Arquivos de perfis ICC +TP_ICM_GAMMABEFOREINPUT;Perfil aplica gama +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_LUMACURVE_BLACKLEVEL;Preto +TP_LUMACURVE_BRIGHTNESS;Brilho +TP_LUMACURVE_COMPRHIGHLIGHTS;Compressão da Luz +TP_LUMACURVE_COMPRSHADOWS;Compressão de Sombras +TP_LUMACURVE_CONTRAST;Contraste +TP_LUMACURVE_CURVEEDITOR;Curva de Luminância +TP_LUMACURVE_LABEL;Curva de Luminância +TP_RAW_DMETHOD;Método +TP_RAW_FALSECOLOR;Supressão de cor falsa +TP_RESIZE_BICUBICSF;Bicúbico (mais suave) +TP_RESIZE_BICUBICSH;Bicúbic (mais nítido) +TP_RESIZE_BICUBIC;Bicúbico +TP_RESIZE_BILINEAR;Bilinear +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_AUTOCROP;Cortar Automaticamente +TP_ROTATE_DEGREE;Graus +TP_ROTATE_FILL;Preencher +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_CURVES;Curves +!CURVEEDITOR_CURVE;Curve +!CURVEEDITOR_CUSTOM;Custom +!CURVEEDITOR_DARKS;Darks +!CURVEEDITOR_HIGHLIGHTS;Highlights +!CURVEEDITOR_LIGHTS;Lights +!CURVEEDITOR_MINMAXCPOINTS;Minima/Maxima control points +!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 +!EXIFFILTER_EXPOSURECOMPENSATION;Exposure Compensation (EV) +!EXIFFILTER_FILETYPE;File Type +!EXIFFILTER_METADATAFILTER;Enable Metadata Filters +!EXPORT_BYPASS_ALL;Select / Unselect All +!EXPORT_BYPASS_COLORDENOISE;Bypass Color denoise +!EXPORT_BYPASS_DEFRINGE;Bypass Defringe +!EXPORT_BYPASS_DIRPYRDENOISE;Bypass Noise Reduction +!EXPORT_BYPASS_DIRPYREQUALIZER;Bypass Contrast by Detail Levels +!EXPORT_BYPASS_LUMADENOISE;Bypass Luma denoise +!EXPORT_BYPASS_RAW_ALL_ENHANCE;Bypass Post Demosaic Artifact/Noise Reduction +!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 +!EXPORT_RESIZEMETHOD;Resize 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.\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\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_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_POPUPRANK;Rank +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!FILEBROWSER_QUERYHINT;Type a partial filename to search for or a comma-separated list.\nE.g. 1001,1004,1199 \n\nCtrl-F to focus to the Find text box.\nEnter to commence search.\nEsc to clear.\nShift-Esc to remove focus. +!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.\nShortcut: i\n\nShortcut in Single Editor Tab Mode: Alt-i +!FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show images recently saved.\nShortcut: Alt-7 +!FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show images not recently saved.\nShortcut: Alt-6 +!FILEBROWSER_SHOWUNCOLORHINT;Show images without Color label.\nShortcut: Alt-0 +!FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +!FILEBROWSER_UNRANK_TOOLTIP;Unrank\nShortcut: Shift-0 +!FILEBROWSER_USETEMPLATE;Use template: +!GENERAL_AFTER;After +!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\nClick right mouse button on image preview to freeze/unfreeze +!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram +!HISTOGRAM_TOOLTIP_FULL;Toggle full (on) or scaled (off) 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;Lab - Chromaticity +!HISTORY_MSG_96;'a' Curve +!HISTORY_MSG_97;'b' Curve +!HISTORY_MSG_98;Demosaicing Method +!HISTORY_MSG_99;Hot/Dead pixel filter +!HISTORY_MSG_100;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;Resizing applies to +!HISTORY_MSG_111;Lab - Avoid color shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;Lab - Protection +!HISTORY_MSG_114;DCB Iterations +!HISTORY_MSG_115;False Color Suppression +!HISTORY_MSG_116;DCB Enhancement +!HISTORY_MSG_117;Raw Red CA Correction +!HISTORY_MSG_118;Raw Blue CA Correction +!HISTORY_MSG_119;Line Noise Filter +!HISTORY_MSG_120;Green Equilibration +!HISTORY_MSG_121;Raw Auto CA +!HISTORY_MSG_122;Dark Frame Auto Select +!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 Select +!HISTORY_MSG_128;Flat Field Blur Radius +!HISTORY_MSG_129;Flat Field Blur Type +!HISTORY_MSG_130;Auto Distorion +!HISTORY_MSG_131;Noise Reduction Luma +!HISTORY_MSG_132;Noise Reduction 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;Edges Sharpening +!HISTORY_MSG_147;ES - Luminance Only +!HISTORY_MSG_148;Microcontrast +!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_150;Post Demosaic Artifact/Noise Reduction +!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;'CC' curve +!HISTORY_MSG_169;'CH' curve +!HISTORY_MSG_170;Vib - Curve +!HISTORY_MSG_171;'LC' curve +!HISTORY_MSG_172;Lab - 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 tones protection +!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 pixels +!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;'CL' curve +!HISTORY_MSG_247;'LH' curve +!HISTORY_MSG_248;'HH' curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +!MAIN_BUTTON_FULLSCREEN;Fullscreen +!MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the Next image relative to image open in Editor\nShortcut: Shift-F4\n\nTo navigate to the Next image relative to thumbnail selected in File Browser\nShortcut: F4 +!MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the Previous image relative to image open in Editor\nShortcut: Shift-F3 \n\nTo navigate to the Previous image relative to thumbnail selected in File Browser\nShortcut: F3 +!MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronize the File Browser with the Editor to reveal the thumbnail of the currently open image, and clear filters in File Browser \nShortcut: x\n\nAs above, but without clearing filters in File Browser\nShortcut: y\n(Note that thumbnail of the open file 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\ndoesn't exist. Please set a correct path in the Preference window. +!MAIN_MSG_SETPATHFIRST;You have to set a target path first in Preferences\nin order to use this function! +!MAIN_MSG_WRITEFAILED;Failed to write\n\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_METADATA_TOOLTIP;Shortcut: Alt-m +!MAIN_TAB_RAW;Raw +!MAIN_TAB_RAW_TOOLTIP;Shortcut: Alt-r +!MAIN_TAB_TRANSFORM_TOOLTIP;Shortcut: Alt-t +!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 10-30%\n\nPreview is rendered slower with Focus Mask turned on. +!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_NA;B = n/a +!NAVIGATOR_B_VALUE;B = %1 +!NAVIGATOR_G_NA;G = n/a +!NAVIGATOR_G_VALUE;G = %1 +!NAVIGATOR_H_NA;H = n/a +!NAVIGATOR_H_VALUE;H = %1 +!NAVIGATOR_LAB_A_NA;a = n/a +!NAVIGATOR_LAB_A_VALUE;a = %1 +!NAVIGATOR_LAB_B_NA;b = n/a +!NAVIGATOR_LAB_B_VALUE;b = %1 +!NAVIGATOR_LAB_L_NA;L = n/a +!NAVIGATOR_LAB_L_VALUE;L = %1 +!NAVIGATOR_R_NA;R = n/a +!NAVIGATOR_R_VALUE;R = %1 +!NAVIGATOR_S_NA;S = n/a +!NAVIGATOR_S_VALUE;S = %1 +!NAVIGATOR_V_NA;V = n/a +!NAVIGATOR_V_VALUE;V = %1 +!NAVIGATOR_XY_FULL;Width = %1, Height = %2 +!NAVIGATOR_XY_NA;x = n/a, y = n/a +!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;CIE Color Appearance Model 2002 +!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_EVERYTHING;Everything +!PARTIALPASTE_FLATFIELDAUTOSELECT;Flat field auto selection +!PARTIALPASTE_FLATFIELDBLURRADIUS;Flat field blur radius +!PARTIALPASTE_FLATFIELDBLURTYPE;Flat field blur type +!PARTIALPASTE_FLATFIELDFILE;Flat field file +!PARTIALPASTE_GRADIENT;Graduated filter +!PARTIALPASTE_HSVEQUALIZER;HSV equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!PARTIALPASTE_LABCURVE;Lab adjustments +!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_PERSPECTIVE;Perspective +!PARTIALPASTE_PREPROCESS_GREENEQUIL;Green equilibration +!PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Apply hot/dead 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_ALLENHANCE;Post-demosaic artifact/noise reduction +!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 +!PREFERENCES_ADD;Add +!PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!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_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_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 scipts 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_DATEFORMATFRAME;Date Format +!PREFERENCES_DIRDARKFRAMES;Dark frames directory +!PREFERENCES_EDITORLAYOUT;Editor Layout +!PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar (de-select for low resolution display) +!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_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;Output device's Yb luminance (%) +!PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogram in left panel +!PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Show embedded JPEG thumbnail if raw is unedited +!PREFERENCES_LANGAUTODETECT;Use OS language setting +!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_MULTITABDUALMON;Multiple Editor Tabs Mode (if available on second monitor) +!PREFERENCES_MULTITAB;Multiple Editor Tabs Mode +!PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails +!PREFERENCES_OVERWRITEOUTPUTFILE;Overwrite existing output files +!PREFERENCES_PANFACTORFRAME;Pan Rate Amplification +!PREFERENCES_PANFACTORLABEL;Factor +!PREFERENCES_PROPERTY;Property +!PREFERENCES_RGBDTL_LABEL;Max number of threads for Noise Reduction +!PREFERENCES_RGBDTL_TOOLTIP;Noise Reduction requires a baseline of about 128MB RAM for a 10MPix image or 512MB for a 40MPix image, and additionally 128MB RAM per thread. The more threads run in parallel, the faster the computation. Leave the setting at "0" to automatically use as many threads as possible. +!PREFERENCES_SELECTFONT;Select font +!PREFERENCES_SET;Set +!PREFERENCES_SHOWEXPOSURECOMPENSATION;Append exposure compensation +!PREFERENCES_SHOWPROFILESELECTOR;Show processing profile selector +!PREFERENCES_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs +!PREFERENCES_SINGLETAB;Single Editor Tab Mode +!PREFERENCES_SLIMUI;Slim interface +!PREFERENCES_SND_BATCHQUEUEDONE;Queue processing done +!PREFERENCES_SND_HELP;Either enter filepath or nothing (for no sound).\nOn Windows use "SystemDefault", "SystemAsterisk" etc. for system sounds.\nOn Linux use "complete", "window-attention" etc. for system sounds. +!PREFERENCES_SND_LNGEDITPROCDONE;Editor processing done +!PREFERENCES_SND_TRESHOLDSECS;after secs +!PREFERENCES_SQUAREDETAILWINDOW;Square detail window (faster) +!PREFERENCES_TAB_PERFORMANCE;Performance +!PREFERENCES_TAB_SOUND;Sounds +!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_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_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing channel-mixer +!TP_BWMIX_BLUE;Blue +!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;Modify luminance in function of hue\nPay attention to extreme values that may cause artifacts +!TP_BWMIX_CYAN;Cyan +!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 simulate shots taken with a colored filter placed in front of the lens. Colored filters reduce transmission of specific range of colors and correspondingly affect their lightness. E.g. a Red filter darkens Blue skies. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_BLUE;Blue Channel +!TP_BWMIX_GAM_GREEN;Green Channel +!TP_BWMIX_GAM_RED;Red Channel +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each channel RGB +!TP_BWMIX_GREEN;Green +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MAGENTA;Magenta +!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 (filter, channel-mixer) to default +!TP_BWMIX_ORANGE;Orange +!TP_BWMIX_PURPLE;Purple +!TP_BWMIX_RED;Red +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all of the mixer options\nTotal displays the sum of RGB values actually applied:\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 (films, landscape, ...) or manual settings of channel-mixer +!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;Channel-Mixer absolute RGB +!TP_BWMIX_SET_RGBREL;Channel-Mixer relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Channel-Mixer absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Channel-Mixer 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_BWMIX_YELLOW;Yellow +!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) RT 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.\n 0=no effect 1=median 2=gaussian.\n\nThese artifacts are due to limitations of CIECAM02. Alternatively, adjust the image to avoid very dark shadows. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from Lab and RGB brightness +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from Lab and RGB colorfulness +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from Lab and RGB saturation +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from Lab 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 Lab and RGB contrast +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from Lab and RGB contrast +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L (Lab) 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 (Lab) 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 Lab values before CIECAM02 adjustments +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RT 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 (Lab) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in Lab 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 Lab and RGB lightness +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model\n\nWB [RT] + [output]:\nRT's white balance is used for the scene, CIECAM02 is set to D50, the output device's white balance is set in Preferences > Color Management\n\nWB [RT+CAT02] + [output]:\nRT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences +!TP_COLORAPP_RSTPRO;Red & skin tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin tones protection (sliders and curves) +!TP_COLORAPP_SHARPCIE;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe with Q/C +!TP_COLORAPP_SHARPCIE_TOOLTIP;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe will use CIECAM02 if enabled. +!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;Change tones and colors to take into account the viewing conditions of the output device\n\nAverage:\nAverage light environment (standard)\nThe image will not change\n\nDim:\nDim environment (TV)\nThe image will become slighty dark\n\nDark:\nDark environment (projector)\nThe image will become more dark\n\nExtremly Dark:\nExtremly dark environment (cutsheet)\nThe image will become very dark +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if source 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 Lab 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_CROP_GTEPASSPORT;Biometric Passport +!TP_CROP_GTFRAME;Frame +!TP_CROP_GTGRID;Grid +!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_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_CHROMA;Chrominance - Master +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on gamma of the input color profile. Gamma of sRGB is assumed, thus if input image is in color profile of a different gamma, luminance noise reduction will vary. +!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_LAB;Lab +!TP_DIRPYRDENOISE_LDETAIL;Luminance Detail +!TP_DIRPYRDENOISE_LUMA;Luminance +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or Lab methods can be used.\n\nFor non-raw images Lab method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_PERF;RGB mode (raw images) +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGB;RGB +!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_THRESHOLD;Threshold +!TP_DISTORTION_AUTO;Auto Distortion Correction +!TP_DISTORTION_AUTO_TIP;(Exprimental) Correct lens distortion automatically for some cameras (Micro 4/3, some compact digital cameras, etc.) +!TP_EPD_EDGESTOPPING;Edge Stopping +!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 via Lab mode (standard) and CIECAM02 mode.\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_EXPOSCORR_LABEL;Raw White & Black Points +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggle execution of auto levels to automatically set parameter values based on image analysis\nEnable Highlight Reconstruction if necessary +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in auto level's 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 following section of the manual to learn how to achieve the best results with double curves:\nThe Toolbox > Exposure Tab > Exposure Panel > Tone Curve +!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_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!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_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 effect of this tool or some of its sub-component is only visible at 1:1 preview scale. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Rotation anchor point X: -100=left edge, 0=center, +100=right edge +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Rotation anchor point Y: -100=top edge, 0=center, +100=bottom edge +!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 automatic exposure +!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 blown 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 simple color matrix by dcraw, enhanced RawTherapee version (whichever is available based on camera model) or embedded in 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. Use only in special cases. +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. Result can be used for calibration purposes, 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;Lab 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;Can be used with the Chromaticity slider and the CC curve. +!TP_LENSGEOM_AUTOCROP;Auto Crop +!TP_LENSGEOM_FILL;Auto fill +!TP_LENSGEOM_LABEL;Lens / Geometry +!TP_LENSPROFILE_FILEDLGFILTERLCP;Lens correction files +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;CA Correction +!TP_LENSPROFILE_USEDIST;Distortion correction +!TP_LENSPROFILE_USEVIGN;Vignetting correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset 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: 0=corners only, 50=halfway to center, 100=to center +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness: 0=rectangle, 50=fitted ellipse, 100=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. Higher = more, lower = less. +!TP_PREPROCESS_GREENEQUIL;Green Equilibration +!TP_PREPROCESS_HOTDEADPIXFILT;Hot/Dead pixel filter +!TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Try to suppress hot and dead 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_BLACKONE;Black Level: Red +!TP_RAWEXPOS_BLACKS;Black Levels +!TP_RAWEXPOS_BLACKTHREE;Black Level: Green 2 +!TP_RAWEXPOS_BLACKTWO;Black Level: Blue +!TP_RAWEXPOS_BLACKZERO;Black Level: Green 1 (lead) +!TP_RAWEXPOS_LINEAR;White Point Correction +!TP_RAWEXPOS_PRESER;Highlight Preservation +!TP_RAWEXPOS_TWOGREEN;Link greens +!TP_RAW_ALLENHANCE;Post-Demosaic Artifact/Noise Reduction +!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 +!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_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 used 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_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_ZOOMFITSCREEN;Fit 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..77728ab2e --- /dev/null +++ b/rtdata/languages/Russian @@ -0,0 +1,1404 @@ +#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-01-04 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_FILEDLGFILTERANY;Любые файлы +CURVEEDITOR_FILEDLGFILTERCURVE;Файлы тоновых кривых +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;Тип: +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_COLORDENOISE;Пропустить удаление цифрового шума +EXPORT_BYPASS_DEFRINGE;Пропустить подавление ореолов +EXPORT_BYPASS_DIRPYRDENOISE;Пропустить подавление шума +EXPORT_BYPASS_DIRPYREQUALIZER;Пропустить контраст в зависимости от детализации +EXPORT_BYPASS_LUMADENOISE;Пропустить подавление яркостного шума +EXPORT_BYPASS_RAW_ALL_ENHANCE;Пропустить пост-демозаик подавление артефактов/шума +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;Метод демозаика +EXPORT_RESIZEMETHOD;Метод масштабирования +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_POPUPCOLORLABEL;Цветовая пометка +FILEBROWSER_POPUPCOPYTO;Скопировать в... +FILEBROWSER_POPUPFILEOPERATIONS;Действия с файлами +FILEBROWSER_POPUPMOVEEND;Переместить в конец очереди +FILEBROWSER_POPUPMOVEHEAD;Переместить в начало очереди +FILEBROWSER_POPUPMOVETO;Переместить в... +FILEBROWSER_POPUPOPEN;Открыть +FILEBROWSER_POPUPPROCESSFAST;Поставить в очередь (Быстрый экспорт) +FILEBROWSER_POPUPPROCESS;Поместить в очередь на обработку +FILEBROWSER_POPUPPROFILEOPERATIONS;Обработка операций профиля +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Горячая клавиша: 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_USETEMPLATE;Использовать шаблон: +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;Удаление шума +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: R +HISTORY_MSG_164;Кривая RGB: G +HISTORY_MSG_165;Кривая RGB: B +HISTORY_MSG_166;Нейтральные уровни +HISTORY_MSG_167;--неиспользуемый-- +HISTORY_MSG_168;'Цц' кривая +HISTORY_MSG_169;'Цо' кривая +HISTORY_MSG_170;Рез: кривая +HISTORY_MSG_171;Кривая 'LC' +HISTORY_MSG_172;LAB: Ограничение LC +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;ФВ: Roundness +HISTORY_MSG_243;КВ: Радиус +HISTORY_MSG_244;КВ: Сила +HISTORY_MSG_245;КВ: Центр +HISTORY_MSG_246;Кривая 'CL' +HISTORY_MSG_247;Кривая 'LH' +HISTORY_MSG_248;Кривая 'HH' +HISTORY_MSG_249;CbDL: Порог +HISTORY_MSG_250;ПШ: Улучшенный +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_TAGGING;Метки +MAIN_TAB_TRANSFORM;Преобразования +MAIN_TAB_TRANSFORM_TOOLTIP;Горячая клавиша: Alt-T +MAIN_TOOLTIP_BACKCOLOR0;Фоновый цвет предпросмотра: Как в теме\nГорячая клавиша: 8 +MAIN_TOOLTIP_BACKCOLOR1;Фоновый цвет предпросмотра: Черный\nГорячая клавиша: 9 +MAIN_TOOLTIP_BACKCOLOR2;Фоновый цвет предпросмотра: Белый\nГорячая клавиша: 0 +MAIN_TOOLTIP_BEFOREAFTERLOCK;Заблокировать / Разблокировать предыдущий вид\n\nЗаблокировать: сохраняет предыдущий вид неизменным.\nПолезно для оценки общего эффекта от применения нескольких инструментов.\nК тому же, сравнения могут быть произведены на любом состоянии истории\n\nРазблокировать: предыдущий вид будет следовать сразу за следующим, показывая состояние изображения до применения текущего инструмента. +MAIN_TOOLTIP_HIDEHP;Показать/скрыть левую панель (включая историю).\nГорячая клавиша: H +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_B_NA;B = н/д +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_G_NA;G = н/д +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_H_NA;H = н/д +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_LAB_A_NA;A = н/д +NAVIGATOR_LAB_A_VALUE;A = %1 +NAVIGATOR_LAB_B_NA;B = н/д +NAVIGATOR_LAB_B_VALUE;B = %1 +NAVIGATOR_LAB_L_NA;L = н/д +NAVIGATOR_LAB_L_VALUE;L = %1 +NAVIGATOR_R_NA;R = н/д +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_S_NA;S = н/д +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_NA;V = н/д +NAVIGATOR_V_VALUE;V = %1 +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_METAICMGROUP;Настройка метаданных/параметров ICM +PARTIALPASTE_PCVIGNETTE;Фильтр виньетирования +PARTIALPASTE_PERSPECTIVE;Перспектива +PARTIALPASTE_PREPROCESS_GREENEQUIL;Выравнивание зелёного канала +PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Применить фильтр горячих/битых пикселей +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_ALLENHANCE;Применить пост-демозаик подавление артефактов/шума +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_BLINKCLIPPED;Мигать проблемными зонами +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_DATEFORMATFRAME;Формат даты +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_GTKTHEME;по умолчанию GTK +PREFERENCES_HISTOGRAMPOSITIONLEFT;Гистограмма на левой панели +PREFERENCES_HLTHRESHOLD;Порог срабатывания пересветов +PREFERENCES_ICCDIR;Каталог ICC профилей +PREFERENCES_IMPROCPARAMS;Обработка по умолчанию +PREFERENCES_INTENT_ABSOLUTE;Абсолютное колориметрическое +PREFERENCES_INTENT_PERCEPTUAL;Перцепционное +PREFERENCES_INTENT_RELATIVE;Относительное колориметрическое +PREFERENCES_INTENT_SATURATION;По насыщенности +PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Показывать встроенную в Raw миниатюру если файл не отредактирован +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_PANFACTORFRAME;Усиление перетаскивания холста +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 или 512 для 40MPix и дополнительно 128MB на поток. Чем больше потоков запущено параллельно, тем быстре рассчёт. Оставьте "0" чтоб автоматически использовать столько потоков, сколько это возможно. +PREFERENCES_SELECTFONT;Выбрать шрифт +PREFERENCES_SELECTLANG;Выберите язык +PREFERENCES_SELECTTHEME;Выбрать тему +PREFERENCES_SET;Установить +PREFERENCES_SHOWBASICEXIF;Показывать основные Exif данные +PREFERENCES_SHOWDATETIME;Показывать дату и время +PREFERENCES_SHOWEXPOSURECOMPENSATION;Добавить компенсацию выдержки +PREFERENCES_SHOWPROFILESELECTOR;Показать выбор профиля обработки +PREFERENCES_SHTHRESHOLD;Порог обрезки теней +PREFERENCES_SINGLETABVERTAB;Одна вкладкой редактирования, вертикальные вкладки +PREFERENCES_SINGLETAB;Одна вкладка редактирования +PREFERENCES_SLIMUI;Тонкий интерфейс +PREFERENCES_SND_BATCHQUEUEDONE;Пакетная обработка завершена +PREFERENCES_SND_HELP;Либо введите имя файла, либо оставьте пустым (без звука). В Windows можно использовать "SystemDefault", "SystemAsterisk" и т.д. для системных звуков. +PREFERENCES_SND_LNGEDITPROCDONE;Обработка в редакторе завершена +PREFERENCES_SND_TRESHOLDSECS;после, секунд +PREFERENCES_SQUAREDETAILWINDOW;Квадратное окно подробностей (быстро) +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_FILEDLGFILTERANY;Любые файлы +PROFILEPANEL_FILEDLGFILTERPP;Профили обработки +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_JPGFILTER;Файлы 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_TIFFFILTER;Файлы TIFF +SAVEDLG_TIFFUNCOMPRESSED;Несжатый TIFF +SAVEDLG_WARNFILENAME;Файл будет наименован +SHCSELECTOR_TOOLTIP;Нажмите правую кнопку мыши для сброса\nпозиции этих трех ползунков +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) +TOOLBAR_TOOLTIP_STRAIGHTEN;Выравнивание (горячая клавиша: S) +TOOLBAR_TOOLTIP_WB;Указать белую точку (горячая клавиша: W) +TP_BWMIX_AUTOCH;Автоопределение +TP_BWMIX_AUTOCH_TIP;Автоматическое вычисление значений миксера каналов +TP_BWMIX_BLUE;Синий +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_CYAN;Циан +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_BLUE;Синий канал +TP_BWMIX_GAM_GREEN;Зелёный канал +TP_BWMIX_GAM_RED;Красный канал +TP_BWMIX_GAM_TOOLTIP;Корректирует гамму для каждого канала RGB. +TP_BWMIX_GREEN;Зелёный +TP_BWMIX_LABEL;Чёрный-и-белый +TP_BWMIX_MAGENTA;Магента +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_ORANGE;Оранжевый +TP_BWMIX_PURPLE;Фиолетовый +TP_BWMIX_RED;Красный +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_SET_RGBABS;Миксер каналов RGB (абсолютный) +TP_BWMIX_SET_RGBREL;Миксер каналов RGB (относительный) +TP_BWMIX_SET_ROYGCBPMABS;Миксер каналов (абсолютный ROYGCBPM) +TP_BWMIX_SET_ROYGCBPMREL;Миксер каналов (относительный ROYGCBPM) +TP_BWMIX_TCMODE_FILMLIKE;Ч&Б плёнка +TP_BWMIX_TCMODE_SATANDVALBLENDING;Ч&Б Смешивание насыщенности и значения +TP_BWMIX_TCMODE_STANDARD;Ч&Б Стандарт +TP_BWMIX_TCMODE_WEIGHTEDSTD;Ч&Б Weighted Standard +TP_BWMIX_VAL;L +TP_BWMIX_YELLOW;Жёлтый +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_GTEPASSPORT;Биометрический паспорт +TP_CROP_GTFRAME;Рамка +TP_CROP_GTGRID;Сетка +TP_CROP_GTHARMMEANS1;Среднее гармоническое 1 +TP_CROP_GTHARMMEANS2;Среднее гармоническое 2 +TP_CROP_GTHARMMEANS3;Среднее гармоническое 3 +TP_CROP_GTHARMMEANS4;Среднее гармоническое 4 +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_CHROMA;Цветность +TP_DIRPYRDENOISE_GAMMA;Гамма +TP_DIRPYRDENOISE_LABEL;Подавление шума +TP_DIRPYRDENOISE_LAB;Lab +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;(Экспериментально) Автоматическая коррекция дисторсии на некоторых камерах (M4/3, некоторые компактные камеры и т.д.) +TP_DISTORTION_LABEL;Дисторсия +TP_EPD_EDGESTOPPING;Определение контуров +TP_EPD_LABEL;Тональная компрессия +TP_EPD_REWEIGHTINGITERATES;Перевзвешивание проходов +TP_EPD_SCALE;Масштаб +TP_EPD_STRENGTH;Интенсивность +TP_EXPOSCORR_LABEL;Точка белого в Raw +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_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_CURV;гамма +TP_GAMMA_FREE;Свободная гамма +TP_GAMMA_OUTPUT;Выходная гамма +TP_GAMMA_SLOP;наклонная (линейная) +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_BLENDCMSMATRIX;Смешивать засветы с матрицей +TP_ICM_BLENDCMSMATRIX_TOOLTIP;Включить восстановление пересветов во время использования профилей ICC на основе LUT +TP_ICM_FILEDLGFILTERANY;Любые файлы +TP_ICM_FILEDLGFILTERICM;Файлы ICC профилей +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_WORKINGPROFILE;Рабочий профиль +TP_IMPULSEDENOISE_LABEL;Подавление импульсного шума +TP_IMPULSEDENOISE_THRESH;Порог +TP_LABCURVE_AVOIDCOLORSHIFT;Избегать сдвига цветов +TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Умещать цвета в диапазон рабочего цветового пространства и применять коррекцию Манселла +TP_LABCURVE_BRIGHTNESS;Яркость +TP_LABCURVE_CHROMATICITY;Цветность +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;Цветность в соответствии с цветностью +TP_LABCURVE_CURVEEDITOR_CH;ЦО +TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Цветность в соответствии с оттенком +TP_LABCURVE_LABEL;Кривые Lab +TP_LABCURVE_LCREDSK;Ограничить LC красными тонами и оттенками кожи +TP_LABCURVE_LCREDSK_TIP;Если включено, то LC-кривая применится лишь для тонов кожи и красных оттенков.\nИначе применяется для всех тонов +TP_LABCURVE_RSTPROTECTION;Защита красных тонов и оттенков кожи +TP_LENSGEOM_AUTOCROP;Автокадрирование +TP_LENSGEOM_FILL;Автозаполнение +TP_LENSGEOM_LABEL;Геометрия +TP_LENSPROFILE_FILEDLGFILTERLCP;Файлы коррекции искажений объектива +TP_LENSPROFILE_LABEL;Профиль коррекции искажений объектива +TP_LENSPROFILE_USECA;Использовать коррекцию ХА +TP_LENSPROFILE_USEDIST;Использовать коррекцию дисторсии +TP_LENSPROFILE_USEVIGN;Использовать коррекцию виньетирования +TP_NEUTRAL;Нейтральный +TP_NEUTRAL_TIP;Сбросить настройки выдержки на средние значения +TP_PERSPECTIVE_HORIZONTAL;Горизонтальная +TP_PERSPECTIVE_LABEL;Перспектива +TP_PERSPECTIVE_VERTICAL;Вертикальная +TP_PREPROCESS_GREENEQUIL;Выравнивание зелёного +TP_PREPROCESS_HOTDEADPIXFILT;Применить фильтр засвеченных/битых пикселей +TP_PREPROCESS_LABEL;Предобработка +TP_PREPROCESS_LINEDENOISE;Фильтр линейного шума +TP_PREPROCESS_NO_FOUND;Ничего не найдено +TP_RAWCACORR_AUTO;Применить автоматическую коррекцию ХА +TP_RAWCACORR_CABLUE;синий +TP_RAWCACORR_CARED;красный +TP_RAWEXPOS_BLACKONE;Уровень черного: Красный +TP_RAWEXPOS_BLACKS;Уровни черного +TP_RAWEXPOS_BLACKTHREE;Уровень черного: Зеленый 2 +TP_RAWEXPOS_BLACKTWO;Уровень черного: Голубой +TP_RAWEXPOS_BLACKZERO;Уровень черного: Зеленый 1 (ведущий) +TP_RAWEXPOS_LINEAR;Точка белого: Линейный фактор корр. +TP_RAWEXPOS_PRESER;Точка белого: сохраняющая HL корр.(EV) +TP_RAWEXPOS_TWOGREEN;Два зеленых совместно +TP_RAW_ALLENHANCE;Применить пост-демозаик подавление артефактов/шума +TP_RAW_DCBENHANCE;Применить шаг улучшения DCB +TP_RAW_DCBITERATIONS;Количество итераций DCB +TP_RAW_DMETHOD;Метод +TP_RAW_FALSECOLOR;Шагов для подавления ложных цветов: +TP_RAW_LABEL;Демозаик +TP_RESIZE_APPLIESTO;Применить к: +TP_RESIZE_BICUBICSF;Мягкий бикубический +TP_RESIZE_BICUBICSH;Резкий бикубический +TP_RESIZE_BICUBIC;Бикубический +TP_RESIZE_BILINEAR;Билинейный +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_RED;R +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_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_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;Вольфрамовый +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. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!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) RT 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.\n 0=no effect 1=median 2=gaussian.\n\nThese artifacts are due to limitations of CIECAM02. Alternatively, adjust the image to avoid very dark shadows. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from Lab and RGB brightness +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from Lab and RGB colorfulness +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from Lab and RGB saturation +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from Lab 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 Lab and RGB contrast +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from Lab and RGB contrast +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L (Lab) 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 (Lab) 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 Lab values before CIECAM02 adjustments +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RT 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 (Lab) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in Lab 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 Lab and RGB lightness +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model\n\nWB [RT] + [output]:\nRT's white balance is used for the scene, CIECAM02 is set to D50, the output device's white balance is set in Preferences > Color Management\n\nWB [RT+CAT02] + [output]:\nRT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences +!TP_COLORAPP_RSTPRO;Red & skin tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin tones protection (sliders and curves) +!TP_COLORAPP_SHARPCIE;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe with Q/C +!TP_COLORAPP_SHARPCIE_TOOLTIP;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe will use CIECAM02 if enabled. +!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;Change tones and colors to take into account the viewing conditions of the output device\n\nAverage:\nAverage light environment (standard)\nThe image will not change\n\nDim:\nDim environment (TV)\nThe image will become slighty dark\n\nDark:\nDark environment (projector)\nThe image will become more dark\n\nExtremly Dark:\nExtremly dark environment (cutsheet)\nThe image will become very dark +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if source 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 Lab 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_DIRPYRDENOISE_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on gamma of the input color profile. Gamma of sRGB is assumed, thus if input image is in color profile of a different gamma, luminance noise reduction will vary. +!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_LDETAIL;Luminance Detail +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or Lab methods can be used.\n\nFor non-raw images Lab method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_PERF;RGB mode (raw images) +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGB;RGB +!TP_EPD_TOOLTIP;Tone mapping is possible via Lab mode (standard) and CIECAM02 mode.\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 following section of the manual to learn how to achieve the best results with double curves:\nThe Toolbox > Exposure Tab > Exposure Panel > Tone Curve +!TP_EXPOSURE_TCMODE_FILMLIKE;Film-like +!TP_EXPOSURE_TCMODE_LABEL1;Curve mode 1 +!TP_EXPOSURE_TCMODE_LABEL2;Curve mode 2 +!TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!TP_GENERAL_11SCALE_TOOLTIP;The effect of this tool or some of its sub-component is only visible at 1:1 preview scale. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Rotation anchor point X: -100=left edge, 0=center, +100=right edge +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Rotation anchor point Y: -100=top edge, 0=center, +100=bottom edge +!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 automatic exposure +!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_TOOLTIP;Save the linear TIFF image before the input profile is applied. Result can be used for calibration purposes, 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_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_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_RSTPRO_TOOLTIP;Can be used with the Chromaticity slider and the CC curve. +!TP_PCVIGNETTE_FEATHER;Feather +!TP_PCVIGNETTE_FEATHER_TOOLTIP;Feathering: 0=corners only, 50=halfway to center, 100=to center +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness: 0=rectangle, 50=fitted ellipse, 100=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. Higher = more, lower = less. +!TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Try to suppress hot and dead pixels +!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 +!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_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 used with CIECAM02. If difference is observed, adjust to taste. +!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 diff --git a/rtdata/languages/Serbian (Cyrilic Characters) b/rtdata/languages/Serbian (Cyrilic Characters) new file mode 100644 index 000000000..e83c86010 --- /dev/null +++ b/rtdata/languages/Serbian (Cyrilic Characters) @@ -0,0 +1,1465 @@ +#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_FILEDLGFILTERANY;Све датотеке +CURVEEDITOR_FILEDLGFILTERCURVE;Датотеке са кривама +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;Врста: +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_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_USETEMPLATE;Искористи шаблон: +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_SAVEAS;Као... +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_TAGGING;Ознаке +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_B_NA;П = ○ +NAVIGATOR_B_VALUE;П = %1 +NAVIGATOR_G_NA;З = ○ +NAVIGATOR_G_VALUE;З = %1 +NAVIGATOR_H_NA;Х = ○ +NAVIGATOR_H_VALUE;Х = %1 +NAVIGATOR_LAB_A_NA;А = ○ +NAVIGATOR_LAB_A_VALUE;А = %1 +NAVIGATOR_LAB_B_NA;Б = ○ +NAVIGATOR_LAB_B_VALUE;Б = %1 +NAVIGATOR_LAB_L_NA;Л = ○ +NAVIGATOR_LAB_L_VALUE;Л = %1 +NAVIGATOR_R_NA;Ц = ○ +NAVIGATOR_R_VALUE;Ц = %1 +NAVIGATOR_S_NA;С = ○ +NAVIGATOR_S_VALUE;С = %1 +NAVIGATOR_V_NA;В = ○ +NAVIGATOR_V_VALUE;В = %1 +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_LUMACURVE;Крива луминасе +PARTIALPASTE_METAICMGROUP;Метаподаци/ИЦМ подешавања +PARTIALPASTE_PERSPECTIVE;Перспектива +PARTIALPASTE_PREPROCESS_GREENEQUIL;Уједначавање зелене +PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Филтер врелих/мртвих пиксела +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_ALLENHANCE;Уклони шум након расклапања мозаика +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;Баланс беле +POPUPBUTTON_SELECTOPTIONHINT;РМБ за измену опције +PREFERENCES_ADD;Додај +PREFERENCES_APPLNEXTSTARTUP;примењује се након поновног покретања +PREFERENCES_AUTOMONPROFILE;Сам примени профиле монитора из оперативног система +PREFERENCES_BATCH_PROCESSING;Обрада закзаног +PREFERENCES_BEHAVIOR;Понашање +PREFERENCES_BLINKCLIPPED;Покажи претамне/пресветле делове +PREFERENCES_CACHECLEARALL;Обриши све +PREFERENCES_CACHECLEARPROFILES;Обриши профиле +PREFERENCES_CACHECLEARTHUMBS;Обриши приказе +PREFERENCES_CACHEFORMAT1;Власнички (брже и боље) +PREFERENCES_CACHEFORMAT2;JPEG (мање места на диску) +PREFERENCES_CACHEMAXENTRIES;Највећи број мест у остави +PREFERENCES_CACHEOPTS;Подешавање оставе +PREFERENCES_CACHETHUMBFORM;Формат умањених приказа +PREFERENCES_CACHETHUMBHEIGHT;Највећа висина приказа +PREFERENCES_CLEARDLG_LINE1;Чишћење оставе +PREFERENCES_CLEARDLG_LINE2;Ово може да потраје неколико секунди. +PREFERENCES_CLEARDLG_TITLE;Сачекајте +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_DATEFORMATFRAME;Формат +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_GTKTHEME;ГТК тема +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_PANFACTORFRAME;Убрзање при померању платна +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_SHOWPROFILESELECTOR;Прикажи избор профила +PREFERENCES_SHTHRESHOLD;Праг за одсечене тамне делове +PREFERENCES_SINGLETABVERTAB;Режим у једном листу, вертикални листови +PREFERENCES_SINGLETAB;Режим у једном листу +PREFERENCES_SLIMUI;Танки изглед +PREFERENCES_SND_BATCHQUEUEDONE;Обрађене су заказане датотеке +PREFERENCES_SND_HELP;Унесите путању до датотеке или оставите празно уколико не желите звук. На Windows-у можете да користите „SystemDefault“, „SystemAsterisk“ за системске звуке. +PREFERENCES_SND_LNGEDITPROCDONE;Уредник је завршио обраду +PREFERENCES_SND_TRESHOLDSECS;бр. секунди +PREFERENCES_SQUAREDETAILWINDOW;Коцкаст прозор са детаљима (брже) +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_FILEDLGFILTERANY;Све датотеке +PROFILEPANEL_FILEDLGFILTERPP;Профили за обраду +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_LOADING;Учитавам датотеку... +PROGRESSDLG_PROCESSING;Обрађујем слику... +PROGRESSDLG_PROFILECHANGEDINBROWSER;Профил измењен у разгледачу +PROGRESSDLG_SAVING;Чувам датотеку... +P_GAMMA_CURV;гама +QINFO_ISO;ИСО +QINFO_NOEXIF;Нису доступни Exif подаци. +SAVEDLG_AUTOSUFFIX;Сам додај суфикс уколико датотека већ постоји +SAVEDLG_FILEFORMAT;Формат датотеке +SAVEDLG_JPEGQUAL;JPEG квалитет +SAVEDLG_JPGFILTER;JPEG датотеке +SAVEDLG_PNGCOMPR;PNG паковање +SAVEDLG_PUTTOQUEUEHEAD;Премешта слику на почетак заказаних +SAVEDLG_PUTTOQUEUETAIL;Премешта слику на крај заказаних +SAVEDLG_PUTTOQUEUE;Заказује слику за обраду +SAVEDLG_SAVEIMMEDIATELY;Одмах сачувај +SAVEDLG_SAVESPP;Сачувај параметре обраде уз слику +SAVEDLG_TIFFFILTER;TIFF датотеке +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_DEGREE;степени: +TP_COARSETRAF_TOOLTIP_HFLIP;Изврће слику хоризонтално +TP_COARSETRAF_TOOLTIP_ROTLEFT;Окреће слику улево +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Окреће слику удесно +TP_COARSETRAF_TOOLTIP_VFLIP;Изврће слику вертикално +TP_COLORBOOST_ACHANNEL;Канал „а“ +TP_COLORBOOST_AMOUNT;Количина +TP_COLORBOOST_AVOIDCOLORCLIP;Избегни одсецање боја +TP_COLORBOOST_BCHANNEL;Канал „б“ +TP_COLORBOOST_CHANNEL;Канал +TP_COLORBOOST_CHSEPARATE;раздвоји +TP_COLORBOOST_ENABLESATLIMITER;Омогући ограничење засићености +TP_COLORBOOST_LABEL;Појачање боја +TP_COLORBOOST_SATLIMIT;Граница за засићеност +TP_COLORDENOISE_EDGESENSITIVE;Осетљиво на ивице +TP_COLORDENOISE_EDGETOLERANCE;Толеранција ивице +TP_COLORDENOISE_LABEL;Уклаљање колорног шума +TP_COLORDENOISE_RADIUS;Полупречник +TP_COLORSHIFT_BLUEYELLOW;Плава-Жута +TP_COLORSHIFT_GREENMAGENTA;Зелена-Магнета +TP_COLORSHIFT_LABEL;Померај боја +TP_CROP_DPI;ТПИ= +TP_CROP_FIXRATIO;Сразмерно: +TP_CROP_GTDIAGONALS;Правило дијагонала +TP_CROP_GTGRID;Мрежа +TP_CROP_GTHARMMEANS1;Златни пресек 1 +TP_CROP_GTHARMMEANS2;Златни пресек 2 +TP_CROP_GTHARMMEANS3;Златни пресек 3 +TP_CROP_GTHARMMEANS4;Златни пресек 4 +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_DETAIL_AMOUNT;Количина +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_EQUALIZER_CONTRAST_MINUS;Контраст - +TP_EQUALIZER_CONTRAST_PLUS;Контраст + +TP_EQUALIZER_FINEST;најфиније +TP_EQUALIZER_LABEL;Таласно уједначење +TP_EQUALIZER_LARGEST;најгрубље +TP_EQUALIZER_NEUTRAL;Неутрално +TP_EXPOSCORR_LABEL;Raw бела тачка +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_EXPO_AFTER; Пре интерполације (пре превода у РГБ) +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_COMMENT;(онемогућен је излазни профил, осим „default“) +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_HSVEQUALIZER1;Црвена +TP_HSVEQUALIZER2;Жута +TP_HSVEQUALIZER3;Лимун +TP_HSVEQUALIZER4;Зелена +TP_HSVEQUALIZER5;Водена +TP_HSVEQUALIZER6;Плава +TP_HSVEQUALIZER7;Љубичаста +TP_HSVEQUALIZER8;Магнета +TP_HSVEQUALIZER_CHANNEL;ХСВ канал +TP_HSVEQUALIZER_HUE;Нијанса +TP_HSVEQUALIZER_LABEL;Уједначење ХСВ канала +TP_HSVEQUALIZER_SAT;Засићеност +TP_HSVEQUALIZER_VAL;Вредност +TP_ICM_BLENDCMSMATRIX;Утопи светле делове у матрицу +TP_ICM_FILEDLGFILTERANY;Било која датотека +TP_ICM_FILEDLGFILTERICM;ИЦЦ профили +TP_ICM_GAMMABEFOREINPUT;Профил за примену Гаме +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_AVOIDCOLORCLIP;Онемогући одсецање боје +TP_LABCURVE_BRIGHTNESS;Осветљеност +TP_LABCURVE_CONTRAST;Контраст +TP_LABCURVE_CURVEEDITOR;Крива светлости +TP_LABCURVE_ENABLESATLIMITER;Укључи граничник засићености +TP_LABCURVE_LABEL;Лаб крива +TP_LABCURVE_SATLIMIT;Граничник засићености +TP_LABCURVE_SATURATION;Засићеност +TP_LENSGEOM_AUTOCROP;Сам исеци +TP_LENSGEOM_FILL;Сам попуни +TP_LENSGEOM_LABEL;Објектив и геометрија +TP_LUMACURVE_BLACKLEVEL;Црна +TP_LUMACURVE_BRIGHTNESS;Осветљење +TP_LUMACURVE_COMPRHIGHLIGHTS;Сабијање светлог +TP_LUMACURVE_COMPRSHADOWS;Сабијање сенки +TP_LUMACURVE_CONTRAST;Контраст +TP_LUMACURVE_CURVEEDITOR;Крива лиминансе +TP_LUMACURVE_LABEL;Крива луминансе +TP_PERSPECTIVE_HORIZONTAL;Хоризонтална +TP_PERSPECTIVE_LABEL;Перспектива +TP_PERSPECTIVE_VERTICAL;Вертикална +TP_PREPROCESS_GREENEQUIL;Калибрација зелене боје +TP_PREPROCESS_HOTDEADPIXFILT;Избаци прегореле и мртве пикселе +TP_PREPROCESS_LABEL;Предобрада +TP_PREPROCESS_LINEDENOISE;Линијски филтер шума +TP_PREPROCESS_NO_FOUND;Није пронађено +TP_RAWCACORR_AUTO;Исправи хроматске аберације +TP_RAWCACORR_CABLUE;Плава +TP_RAWCACORR_CARED;Црвена +TP_RAWEXPOS_BLACKONE;Ниво црне: Црвена +TP_RAWEXPOS_BLACKS;Ниво црне +TP_RAWEXPOS_BLACKTHREE;Ниво црне: Зелена 2 +TP_RAWEXPOS_BLACKTWO;Ниво црне: Плава +TP_RAWEXPOS_BLACKZERO;Ниво црне: Зелена 1 (водећа) +TP_RAWEXPOS_LINEAR;Линеарни фактор корекције +TP_RAWEXPOS_PRESER;Очување светлих делова +TP_RAWEXPOS_TWOGREEN;Обе зелене +TP_RAW_ALLENHANCE;Уклони артафакте/шум након расклапања +TP_RAW_DCBENHANCE;Примени ДЦБ побољшање +TP_RAW_DCBITERATIONS;Број ДЦБ пролаза +TP_RAW_DMETHOD;Начин +TP_RAW_FALSECOLOR;Кораци за пригушивање лажне боје +TP_RAW_LABEL;Расклапање мозаика +TP_RESIZE_APPLIESTO;Примени на: +TP_RESIZE_BICUBICSF;Бикубично (мекше) +TP_RESIZE_BICUBICSH;Бикубично (оштрије) +TP_RESIZE_BICUBIC;Бикубично +TP_RESIZE_BILINEAR;Билинеарно +TP_RESIZE_CROPPEDAREA;Исечену област +TP_RESIZE_DOWNSCALEB;Смањење размере (боље) +TP_RESIZE_DOWNSCALEF;Смањење размере (брже) +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_AUTOCROP;Сам исеци +TP_ROTATE_DEGREE;Степени: +TP_ROTATE_FILL;Попуни +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 +!EXIFFILTER_EXPOSURECOMPENSATION;Exposure Compensation (EV) +!EXPORT_BYPASS_ALL;Select / Unselect All +!EXPORT_BYPASS_COLORDENOISE;Bypass Color denoise +!EXPORT_BYPASS_DEFRINGE;Bypass Defringe +!EXPORT_BYPASS_DIRPYRDENOISE;Bypass Noise Reduction +!EXPORT_BYPASS_DIRPYREQUALIZER;Bypass Contrast by Detail Levels +!EXPORT_BYPASS_LUMADENOISE;Bypass Luma denoise +!EXPORT_BYPASS_RAW_ALL_ENHANCE;Bypass Post Demosaic Artifact/Noise Reduction +!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 +!EXPORT_RESIZEMETHOD;Resize 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_POPUPPROCESSFAST;Put to Queue (Fast export) +!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_UNRANK_TOOLTIP;Unrank\nShortcut: Shift-0 +!GENERAL_AUTO;Automatic +!GENERAL_CLOSE;Close +!GENERAL_WARNING;Warning +!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram +!HISTOGRAM_TOOLTIP_FULL;Toggle full (on) or scaled (off) 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;'CC' curve +!HISTORY_MSG_169;'CH' curve +!HISTORY_MSG_170;Vib - Curve +!HISTORY_MSG_171;'LC' curve +!HISTORY_MSG_172;Lab - 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 tones protection +!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 pixels +!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;'CL' curve +!HISTORY_MSG_247;'LH' curve +!HISTORY_MSG_248;'HH' curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +!MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the Next image relative to image open in Editor\nShortcut: Shift-F4\n\nTo navigate to the Next image relative to thumbnail selected in File Browser\nShortcut: F4 +!MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the Previous image relative to image open in Editor\nShortcut: Shift-F3 \n\nTo navigate to the Previous image relative to thumbnail selected in File Browser\nShortcut: F3 +!MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronize the File Browser with the Editor to reveal the thumbnail of the currently open image, and clear filters in File Browser \nShortcut: x\n\nAs above, but without clearing filters in File Browser\nShortcut: y\n(Note that thumbnail of the open file 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\ndoesn't exist. Please set a correct path in the Preference window. +!MAIN_MSG_SETPATHFIRST;You have to set a target path first in Preferences\nin order to use this function! +!MAIN_MSG_WRITEFAILED;Failed to write\n\n"%1"\n\nMake sure that the folder exists and that you have write permission to it. +!MAIN_TAB_EXPORT; Fast Export +!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 10-30%\n\nPreview is rendered slower with Focus Mask turned on. +!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_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;CIE Color Appearance Model 2002 +!PARTIALPASTE_EPD;Tone mapping +!PARTIALPASTE_GRADIENT;Graduated filter +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!PARTIALPASTE_RGBCURVES;RGB curves +!PARTIALPASTE_VIBRANCE;Vibrance +!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_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_CUSTPROFBUILDKEYFORMAT;Keys format +!PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Name +!PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID +!PREFERENCES_D50;5000K +!PREFERENCES_D55;5500K +!PREFERENCES_D60;6000K +!PREFERENCES_D65;6500K +!PREFERENCES_FLUOF2;Fluorescent F2 +!PREFERENCES_FLUOF7;Fluorescent F7 +!PREFERENCES_FLUOF11;Fluorescent F11 +!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;Output device's Yb luminance (%) +!PREFERENCES_MENUGROUPEXTPROGS;Group "Open with" +!PREFERENCES_RGBDTL_LABEL;Max number of threads for Noise Reduction +!PREFERENCES_RGBDTL_TOOLTIP;Noise Reduction requires a baseline of about 128MB RAM for a 10MPix image or 512MB for a 40MPix image, and additionally 128MB RAM per thread. The more threads run in parallel, the faster the computation. Leave the setting at "0" to automatically use as many threads as possible. +!PREFERENCES_SHOWEXPOSURECOMPENSATION;Append exposure compensation +!PREFERENCES_TAB_PERFORMANCE;Performance +!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.) +!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_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing channel-mixer +!TP_BWMIX_BLUE;Blue +!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;Modify luminance in function of hue\nPay attention to extreme values that may cause artifacts +!TP_BWMIX_CYAN;Cyan +!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 simulate shots taken with a colored filter placed in front of the lens. Colored filters reduce transmission of specific range of colors and correspondingly affect their lightness. E.g. a Red filter darkens Blue skies. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_BLUE;Blue Channel +!TP_BWMIX_GAM_GREEN;Green Channel +!TP_BWMIX_GAM_RED;Red Channel +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each channel RGB +!TP_BWMIX_GREEN;Green +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MAGENTA;Magenta +!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 (filter, channel-mixer) to default +!TP_BWMIX_ORANGE;Orange +!TP_BWMIX_PURPLE;Purple +!TP_BWMIX_RED;Red +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all of the mixer options\nTotal displays the sum of RGB values actually applied:\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 (films, landscape, ...) or manual settings of channel-mixer +!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;Channel-Mixer absolute RGB +!TP_BWMIX_SET_RGBREL;Channel-Mixer relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Channel-Mixer absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Channel-Mixer 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_BWMIX_YELLOW;Yellow +!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) RT 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.\n 0=no effect 1=median 2=gaussian.\n\nThese artifacts are due to limitations of CIECAM02. Alternatively, adjust the image to avoid very dark shadows. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from Lab and RGB brightness +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from Lab and RGB colorfulness +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from Lab and RGB saturation +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from Lab 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 Lab and RGB contrast +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from Lab and RGB contrast +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L (Lab) 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 (Lab) 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 Lab values before CIECAM02 adjustments +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RT 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 (Lab) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in Lab 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 Lab and RGB lightness +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model\n\nWB [RT] + [output]:\nRT's white balance is used for the scene, CIECAM02 is set to D50, the output device's white balance is set in Preferences > Color Management\n\nWB [RT+CAT02] + [output]:\nRT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences +!TP_COLORAPP_RSTPRO;Red & skin tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin tones protection (sliders and curves) +!TP_COLORAPP_SHARPCIE;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe with Q/C +!TP_COLORAPP_SHARPCIE_TOOLTIP;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe will use CIECAM02 if enabled. +!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;Change tones and colors to take into account the viewing conditions of the output device\n\nAverage:\nAverage light environment (standard)\nThe image will not change\n\nDim:\nDim environment (TV)\nThe image will become slighty dark\n\nDark:\nDark environment (projector)\nThe image will become more dark\n\nExtremly Dark:\nExtremly dark environment (cutsheet)\nThe image will become very dark +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if source 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 Lab 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_CROP_GTEPASSPORT;Biometric Passport +!TP_CROP_GTFRAME;Frame +!TP_DIRPYRDENOISE_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on gamma of the input color profile. Gamma of sRGB is assumed, thus if input image is in color profile of a different gamma, luminance noise reduction will vary. +!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_LDETAIL;Luminance Detail +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or Lab methods can be used.\n\nFor non-raw images Lab method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_PERF;RGB mode (raw images) +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGB;RGB +!TP_EPD_EDGESTOPPING;Edge Stopping +!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 via Lab mode (standard) and CIECAM02 mode.\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;Toggle execution of auto levels to automatically set parameter values based on image analysis\nEnable Highlight Reconstruction if necessary +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in auto level's operation +!TP_EXPOSURE_CURVEEDITOR1;Tone Curve 1 +!TP_EXPOSURE_CURVEEDITOR2;Tone Curve 2 +!TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Please refer to the following section of the manual to learn how to achieve the best results with double curves:\nThe Toolbox > Exposure Tab > Exposure Panel > Tone Curve +!TP_EXPOSURE_TCMODE_FILMLIKE;Film-like +!TP_EXPOSURE_TCMODE_LABEL1;Curve mode 1 +!TP_EXPOSURE_TCMODE_LABEL2;Curve mode 2 +!TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!TP_GAMMA_CURV;Gamma +!TP_GENERAL_11SCALE_TOOLTIP;The effect of this tool or some of its sub-component is only visible at 1:1 preview scale. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Rotation anchor point X: -100=left edge, 0=center, +100=right edge +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Rotation anchor point Y: -100=top edge, 0=center, +100=bottom edge +!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 automatic exposure +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover blown 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 simple color matrix by dcraw, enhanced RawTherapee version (whichever is available based on camera model) or embedded in 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. Use only in special cases. +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. Result can be used for calibration purposes, 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;Can be used with the Chromaticity slider and the CC curve. +!TP_LENSPROFILE_FILEDLGFILTERLCP;Lens correction files +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;CA Correction +!TP_LENSPROFILE_USEDIST;Distortion correction +!TP_LENSPROFILE_USEVIGN;Vignetting correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset 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: 0=corners only, 50=halfway to center, 100=to center +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness: 0=rectangle, 50=fitted ellipse, 100=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. Higher = more, lower = less. +!TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Try to suppress hot and dead pixels +!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 +!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_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 used 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_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 diff --git a/rtdata/languages/Serbian (Latin Characters) b/rtdata/languages/Serbian (Latin Characters) new file mode 100644 index 000000000..4afcf93b5 --- /dev/null +++ b/rtdata/languages/Serbian (Latin Characters) @@ -0,0 +1,1465 @@ +#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_FILEDLGFILTERANY;Sve datoteke +CURVEEDITOR_FILEDLGFILTERCURVE;Datoteke sa krivama +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: +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_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_USETEMPLATE;Iskoristi šablon: +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_SAVEAS;Kao... +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_TAGGING;Oznake +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_B_NA;P = ○ +NAVIGATOR_B_VALUE;P = %1 +NAVIGATOR_G_NA;Z = ○ +NAVIGATOR_G_VALUE;Z = %1 +NAVIGATOR_H_NA;H = ○ +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_LAB_A_NA;A = ○ +NAVIGATOR_LAB_A_VALUE;A = %1 +NAVIGATOR_LAB_B_NA;B = ○ +NAVIGATOR_LAB_B_VALUE;B = %1 +NAVIGATOR_LAB_L_NA;L = ○ +NAVIGATOR_LAB_L_VALUE;L = %1 +NAVIGATOR_R_NA;C = ○ +NAVIGATOR_R_VALUE;C = %1 +NAVIGATOR_S_NA;S = ○ +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_NA;V = ○ +NAVIGATOR_V_VALUE;V = %1 +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_LUMACURVE;Kriva luminase +PARTIALPASTE_METAICMGROUP;Metapodaci/ICM podešavanja +PARTIALPASTE_PERSPECTIVE;Perspektiva +PARTIALPASTE_PREPROCESS_GREENEQUIL;Ujednačavanje zelene +PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Filter vrelih/mrtvih piksela +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_ALLENHANCE;Ukloni šum nakon rasklapanja mozaika +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 +POPUPBUTTON_SELECTOPTIONHINT;RMB za izmenu opcije +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_BLINKCLIPPED;Pokaži pretamne/presvetle delove +PREFERENCES_CACHECLEARALL;Obriši sve +PREFERENCES_CACHECLEARPROFILES;Obriši profile +PREFERENCES_CACHECLEARTHUMBS;Obriši prikaze +PREFERENCES_CACHEFORMAT1;Vlasnički (brže i bolje) +PREFERENCES_CACHEFORMAT2;JPEG (manje mesta na disku) +PREFERENCES_CACHEMAXENTRIES;Najveći broj mest u ostavi +PREFERENCES_CACHEOPTS;Podešavanje ostave +PREFERENCES_CACHETHUMBFORM;Format umanjenih prikaza +PREFERENCES_CACHETHUMBHEIGHT;Najveća visina prikaza +PREFERENCES_CLEARDLG_LINE1;Čišćenje ostave +PREFERENCES_CLEARDLG_LINE2;Ovo može da potraje nekoliko sekundi. +PREFERENCES_CLEARDLG_TITLE;Sačekajte +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_DATEFORMATFRAME;Format +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_GTKTHEME;GTK tema +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_PANFACTORFRAME;Ubrzanje pri pomeranju platna +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_SHOWPROFILESELECTOR;Prikaži izbor profila +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_SQUAREDETAILWINDOW;Kockast prozor sa detaljima (brže) +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_FILEDLGFILTERANY;Sve datoteke +PROFILEPANEL_FILEDLGFILTERPP;Profili za obradu +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_LOADING;Učitavam datoteku... +PROGRESSDLG_PROCESSING;Obrađujem sliku... +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profil izmenjen u razgledaču +PROGRESSDLG_SAVING;Čuvam datoteku... +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_JPGFILTER;JPEG datoteke +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_TIFFFILTER;TIFF datoteke +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_DEGREE;stepeni: +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_COLORBOOST_ACHANNEL;Kanal „a“ +TP_COLORBOOST_AMOUNT;Količina +TP_COLORBOOST_AVOIDCOLORCLIP;Izbegni odsecanje boja +TP_COLORBOOST_BCHANNEL;Kanal „b“ +TP_COLORBOOST_CHANNEL;Kanal +TP_COLORBOOST_CHSEPARATE;razdvoji +TP_COLORBOOST_ENABLESATLIMITER;Omogući ograničenje zasićenosti +TP_COLORBOOST_LABEL;Pojačanje boja +TP_COLORBOOST_SATLIMIT;Granica za zasićenost +TP_COLORDENOISE_EDGESENSITIVE;Osetljivo na ivice +TP_COLORDENOISE_EDGETOLERANCE;Tolerancija ivice +TP_COLORDENOISE_LABEL;Uklaljanje kolornog šuma +TP_COLORDENOISE_RADIUS;Poluprečnik +TP_COLORSHIFT_BLUEYELLOW;Plava-Žuta +TP_COLORSHIFT_GREENMAGENTA;Zelena-Magneta +TP_COLORSHIFT_LABEL;Pomeraj boja +TP_CROP_DPI;TPI= +TP_CROP_FIXRATIO;Srazmerno: +TP_CROP_GTDIAGONALS;Pravilo dijagonala +TP_CROP_GTGRID;Mreža +TP_CROP_GTHARMMEANS1;Zlatni presek 1 +TP_CROP_GTHARMMEANS2;Zlatni presek 2 +TP_CROP_GTHARMMEANS3;Zlatni presek 3 +TP_CROP_GTHARMMEANS4;Zlatni presek 4 +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_DETAIL_AMOUNT;Količina +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_EQUALIZER_CONTRAST_MINUS;Kontrast - +TP_EQUALIZER_CONTRAST_PLUS;Kontrast + +TP_EQUALIZER_FINEST;najfinije +TP_EQUALIZER_LABEL;Talasno ujednačenje +TP_EQUALIZER_LARGEST;najgrublje +TP_EQUALIZER_NEUTRAL;Neutralno +TP_EXPOSCORR_LABEL;Raw bela tačka +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_EXPO_AFTER; Pre interpolacije (pre prevoda u RGB) +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_COMMENT;(onemogućen je izlazni profil, osim „default“) +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_HSVEQUALIZER1;Crvena +TP_HSVEQUALIZER2;Žuta +TP_HSVEQUALIZER3;Limun +TP_HSVEQUALIZER4;Zelena +TP_HSVEQUALIZER5;Vodena +TP_HSVEQUALIZER6;Plava +TP_HSVEQUALIZER7;Ljubičasta +TP_HSVEQUALIZER8;Magneta +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_FILEDLGFILTERANY;Bilo koja datoteka +TP_ICM_FILEDLGFILTERICM;ICC profili +TP_ICM_GAMMABEFOREINPUT;Profil za primenu Game +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_AVOIDCOLORCLIP;Onemogući odsecanje boje +TP_LABCURVE_BRIGHTNESS;Osvetljenost +TP_LABCURVE_CONTRAST;Kontrast +TP_LABCURVE_CURVEEDITOR;Kriva svetlosti +TP_LABCURVE_ENABLESATLIMITER;Uključi graničnik zasićenosti +TP_LABCURVE_LABEL;Lab kriva +TP_LABCURVE_SATLIMIT;Graničnik zasićenosti +TP_LABCURVE_SATURATION;Zasićenost +TP_LENSGEOM_AUTOCROP;Sam iseci +TP_LENSGEOM_FILL;Sam popuni +TP_LENSGEOM_LABEL;Objektiv i geometrija +TP_LUMACURVE_BLACKLEVEL;Crna +TP_LUMACURVE_BRIGHTNESS;Osvetljenje +TP_LUMACURVE_COMPRHIGHLIGHTS;Sabijanje svetlog +TP_LUMACURVE_COMPRSHADOWS;Sabijanje senki +TP_LUMACURVE_CONTRAST;Kontrast +TP_LUMACURVE_CURVEEDITOR;Kriva liminanse +TP_LUMACURVE_LABEL;Kriva luminanse +TP_PERSPECTIVE_HORIZONTAL;Horizontalna +TP_PERSPECTIVE_LABEL;Perspektiva +TP_PERSPECTIVE_VERTICAL;Vertikalna +TP_PREPROCESS_GREENEQUIL;Kalibracija zelene boje +TP_PREPROCESS_HOTDEADPIXFILT;Izbaci pregorele i mrtve piksele +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_BLACKONE;Nivo crne: Crvena +TP_RAWEXPOS_BLACKS;Nivo crne +TP_RAWEXPOS_BLACKTHREE;Nivo crne: Zelena 2 +TP_RAWEXPOS_BLACKTWO;Nivo crne: Plava +TP_RAWEXPOS_BLACKZERO;Nivo crne: Zelena 1 (vodeća) +TP_RAWEXPOS_LINEAR;Linearni faktor korekcije +TP_RAWEXPOS_PRESER;Očuvanje svetlih delova +TP_RAWEXPOS_TWOGREEN;Obe zelene +TP_RAW_ALLENHANCE;Ukloni artafakte/šum nakon rasklapanja +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_BICUBICSF;Bikubično (mekše) +TP_RESIZE_BICUBICSH;Bikubično (oštrije) +TP_RESIZE_BICUBIC;Bikubično +TP_RESIZE_BILINEAR;Bilinearno +TP_RESIZE_CROPPEDAREA;Isečenu oblast +TP_RESIZE_DOWNSCALEB;Smanjenje razmere (bolje) +TP_RESIZE_DOWNSCALEF;Smanjenje razmere (brže) +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_AUTOCROP;Sam iseci +TP_ROTATE_DEGREE;Stepeni: +TP_ROTATE_FILL;Popuni +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 +!EXIFFILTER_EXPOSURECOMPENSATION;Exposure Compensation (EV) +!EXPORT_BYPASS_ALL;Select / Unselect All +!EXPORT_BYPASS_COLORDENOISE;Bypass Color denoise +!EXPORT_BYPASS_DEFRINGE;Bypass Defringe +!EXPORT_BYPASS_DIRPYRDENOISE;Bypass Noise Reduction +!EXPORT_BYPASS_DIRPYREQUALIZER;Bypass Contrast by Detail Levels +!EXPORT_BYPASS_LUMADENOISE;Bypass Luma denoise +!EXPORT_BYPASS_RAW_ALL_ENHANCE;Bypass Post Demosaic Artifact/Noise Reduction +!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 +!EXPORT_RESIZEMETHOD;Resize 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_POPUPPROCESSFAST;Put to Queue (Fast export) +!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_UNRANK_TOOLTIP;Unrank\nShortcut: Shift-0 +!GENERAL_AUTO;Automatic +!GENERAL_CLOSE;Close +!GENERAL_WARNING;Warning +!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram +!HISTOGRAM_TOOLTIP_FULL;Toggle full (on) or scaled (off) 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;'CC' curve +!HISTORY_MSG_169;'CH' curve +!HISTORY_MSG_170;Vib - Curve +!HISTORY_MSG_171;'LC' curve +!HISTORY_MSG_172;Lab - 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 tones protection +!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 pixels +!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;'CL' curve +!HISTORY_MSG_247;'LH' curve +!HISTORY_MSG_248;'HH' curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +!MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the Next image relative to image open in Editor\nShortcut: Shift-F4\n\nTo navigate to the Next image relative to thumbnail selected in File Browser\nShortcut: F4 +!MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the Previous image relative to image open in Editor\nShortcut: Shift-F3 \n\nTo navigate to the Previous image relative to thumbnail selected in File Browser\nShortcut: F3 +!MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronize the File Browser with the Editor to reveal the thumbnail of the currently open image, and clear filters in File Browser \nShortcut: x\n\nAs above, but without clearing filters in File Browser\nShortcut: y\n(Note that thumbnail of the open file 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\ndoesn't exist. Please set a correct path in the Preference window. +!MAIN_MSG_SETPATHFIRST;You have to set a target path first in Preferences\nin order to use this function! +!MAIN_MSG_WRITEFAILED;Failed to write\n\n"%1"\n\nMake sure that the folder exists and that you have write permission to it. +!MAIN_TAB_EXPORT; Fast Export +!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 10-30%\n\nPreview is rendered slower with Focus Mask turned on. +!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_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;CIE Color Appearance Model 2002 +!PARTIALPASTE_EPD;Tone mapping +!PARTIALPASTE_GRADIENT;Graduated filter +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!PARTIALPASTE_RGBCURVES;RGB curves +!PARTIALPASTE_VIBRANCE;Vibrance +!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_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_CUSTPROFBUILDKEYFORMAT;Keys format +!PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Name +!PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID +!PREFERENCES_D50;5000K +!PREFERENCES_D55;5500K +!PREFERENCES_D60;6000K +!PREFERENCES_D65;6500K +!PREFERENCES_FLUOF2;Fluorescent F2 +!PREFERENCES_FLUOF7;Fluorescent F7 +!PREFERENCES_FLUOF11;Fluorescent F11 +!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;Output device's Yb luminance (%) +!PREFERENCES_MENUGROUPEXTPROGS;Group "Open with" +!PREFERENCES_RGBDTL_LABEL;Max number of threads for Noise Reduction +!PREFERENCES_RGBDTL_TOOLTIP;Noise Reduction requires a baseline of about 128MB RAM for a 10MPix image or 512MB for a 40MPix image, and additionally 128MB RAM per thread. The more threads run in parallel, the faster the computation. Leave the setting at "0" to automatically use as many threads as possible. +!PREFERENCES_SHOWEXPOSURECOMPENSATION;Append exposure compensation +!PREFERENCES_TAB_PERFORMANCE;Performance +!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.) +!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_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing channel-mixer +!TP_BWMIX_BLUE;Blue +!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;Modify luminance in function of hue\nPay attention to extreme values that may cause artifacts +!TP_BWMIX_CYAN;Cyan +!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 simulate shots taken with a colored filter placed in front of the lens. Colored filters reduce transmission of specific range of colors and correspondingly affect their lightness. E.g. a Red filter darkens Blue skies. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_BLUE;Blue Channel +!TP_BWMIX_GAM_GREEN;Green Channel +!TP_BWMIX_GAM_RED;Red Channel +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each channel RGB +!TP_BWMIX_GREEN;Green +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MAGENTA;Magenta +!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 (filter, channel-mixer) to default +!TP_BWMIX_ORANGE;Orange +!TP_BWMIX_PURPLE;Purple +!TP_BWMIX_RED;Red +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all of the mixer options\nTotal displays the sum of RGB values actually applied:\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 (films, landscape, ...) or manual settings of channel-mixer +!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;Channel-Mixer absolute RGB +!TP_BWMIX_SET_RGBREL;Channel-Mixer relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Channel-Mixer absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Channel-Mixer 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_BWMIX_YELLOW;Yellow +!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) RT 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.\n 0=no effect 1=median 2=gaussian.\n\nThese artifacts are due to limitations of CIECAM02. Alternatively, adjust the image to avoid very dark shadows. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from Lab and RGB brightness +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from Lab and RGB colorfulness +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from Lab and RGB saturation +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from Lab 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 Lab and RGB contrast +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from Lab and RGB contrast +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L (Lab) 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 (Lab) 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 Lab values before CIECAM02 adjustments +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RT 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 (Lab) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in Lab 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 Lab and RGB lightness +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model\n\nWB [RT] + [output]:\nRT's white balance is used for the scene, CIECAM02 is set to D50, the output device's white balance is set in Preferences > Color Management\n\nWB [RT+CAT02] + [output]:\nRT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences +!TP_COLORAPP_RSTPRO;Red & skin tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin tones protection (sliders and curves) +!TP_COLORAPP_SHARPCIE;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe with Q/C +!TP_COLORAPP_SHARPCIE_TOOLTIP;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe will use CIECAM02 if enabled. +!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;Change tones and colors to take into account the viewing conditions of the output device\n\nAverage:\nAverage light environment (standard)\nThe image will not change\n\nDim:\nDim environment (TV)\nThe image will become slighty dark\n\nDark:\nDark environment (projector)\nThe image will become more dark\n\nExtremly Dark:\nExtremly dark environment (cutsheet)\nThe image will become very dark +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if source 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 Lab 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_CROP_GTEPASSPORT;Biometric Passport +!TP_CROP_GTFRAME;Frame +!TP_DIRPYRDENOISE_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on gamma of the input color profile. Gamma of sRGB is assumed, thus if input image is in color profile of a different gamma, luminance noise reduction will vary. +!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_LDETAIL;Luminance Detail +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or Lab methods can be used.\n\nFor non-raw images Lab method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_PERF;RGB mode (raw images) +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGB;RGB +!TP_EPD_EDGESTOPPING;Edge Stopping +!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 via Lab mode (standard) and CIECAM02 mode.\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;Toggle execution of auto levels to automatically set parameter values based on image analysis\nEnable Highlight Reconstruction if necessary +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in auto level's operation +!TP_EXPOSURE_CURVEEDITOR1;Tone Curve 1 +!TP_EXPOSURE_CURVEEDITOR2;Tone Curve 2 +!TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Please refer to the following section of the manual to learn how to achieve the best results with double curves:\nThe Toolbox > Exposure Tab > Exposure Panel > Tone Curve +!TP_EXPOSURE_TCMODE_FILMLIKE;Film-like +!TP_EXPOSURE_TCMODE_LABEL1;Curve mode 1 +!TP_EXPOSURE_TCMODE_LABEL2;Curve mode 2 +!TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!TP_GAMMA_CURV;Gamma +!TP_GENERAL_11SCALE_TOOLTIP;The effect of this tool or some of its sub-component is only visible at 1:1 preview scale. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Rotation anchor point X: -100=left edge, 0=center, +100=right edge +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Rotation anchor point Y: -100=top edge, 0=center, +100=bottom edge +!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 automatic exposure +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover blown 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 simple color matrix by dcraw, enhanced RawTherapee version (whichever is available based on camera model) or embedded in 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. Use only in special cases. +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. Result can be used for calibration purposes, 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;Can be used with the Chromaticity slider and the CC curve. +!TP_LENSPROFILE_FILEDLGFILTERLCP;Lens correction files +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;CA Correction +!TP_LENSPROFILE_USEDIST;Distortion correction +!TP_LENSPROFILE_USEVIGN;Vignetting correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset 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: 0=corners only, 50=halfway to center, 100=to center +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness: 0=rectangle, 50=fitted ellipse, 100=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. Higher = more, lower = less. +!TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Try to suppress hot and dead pixels +!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 +!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_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 used 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_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 diff --git a/rtdata/languages/Slovak b/rtdata/languages/Slovak new file mode 100644 index 000000000..db259c7af --- /dev/null +++ b/rtdata/languages/Slovak @@ -0,0 +1,1453 @@ +#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_FILEDLGFILTERANY;Všetky súbory +CURVEEDITOR_FILEDLGFILTERCURVE;Súbory kriviek +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: +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_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_USETEMPLATE;Použiť šablónu: +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_SAVEAS;Ako... +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_TAGGING;Tagging +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_B_NA;B = n/a +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_V_VALUE;V = %1 +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_LUMACURVE;Krivka svietivosti +PARTIALPASTE_METAICMGROUP;Nastavenia metadát/ICM +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_BLINKCLIPPED;Blikať orezanými miestami +PREFERENCES_CACHECLEARALL;Vyčistiť všetko +PREFERENCES_CACHECLEARPROFILES;Vyčistiť profily +PREFERENCES_CACHECLEARTHUMBS;Vyčistiť zmenšeniny +PREFERENCES_CACHEFORMAT1;Vlastné (rýchlejšie a kvalitnejšie) +PREFERENCES_CACHEFORMAT2;JPEG (menšia veľkosť na disku) +PREFERENCES_CACHEMAXENTRIES;Maximálny počet vstupov v cache +PREFERENCES_CACHEOPTS;Možnosti cache +PREFERENCES_CACHETHUMBFORM;Formát zmenšenín pre cache +PREFERENCES_CACHETHUMBHEIGHT;Maximálna výška zmenšenín +PREFERENCES_CLEARDLG_LINE1;Čistím cache +PREFERENCES_CLEARDLG_LINE2;Môže to pár sekúnd trvať. +PREFERENCES_CLEARDLG_TITLE;Prosím, čakajte. +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_GTKTHEME;GTK predvolený +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_FILEDLGFILTERANY;Všetky súbory +PROFILEPANEL_FILEDLGFILTERPP;Profily spracovania +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_LOADING;Načítava sa súbor... +PROGRESSDLG_PROCESSING;Spracúva sa obrázok... +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profil zmenený v prehliadači +PROGRESSDLG_SAVING;Ukladá sa súbor... +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_JPGFILTER;JPEG súbory +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_TIFFFILTER;TIFF súbory +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_DEGREE;stupeň: +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_COLORBOOST_ACHANNEL;Kanál "a" +TP_COLORBOOST_AMOUNT;Množstvo +TP_COLORBOOST_AVOIDCOLORCLIP;Vyhnúť sa orezaniu farieb +TP_COLORBOOST_BCHANNEL;Kanál "b" +TP_COLORBOOST_CHANNEL;Kanál +TP_COLORBOOST_CHSEPARATE;oddelené +TP_COLORBOOST_ENABLESATLIMITER;Povoliť obmedzovať sýtosti +TP_COLORBOOST_LABEL;Zosilnenie farieb +TP_COLORBOOST_SATLIMIT;Hranica sýtosti +TP_COLORDENOISE_EDGESENSITIVE;Citlivá na okraje +TP_COLORDENOISE_EDGETOLERANCE;Tolerancia okrajov +TP_COLORDENOISE_LABEL;Redukcia farebného šumu +TP_COLORDENOISE_RADIUS;Polomer +TP_COLORSHIFT_BLUEYELLOW;Modrá-žltá +TP_COLORSHIFT_GREENMAGENTA;Zelená-fialová +TP_COLORSHIFT_LABEL;Farebný posun +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;Pevný pomer: +TP_CROP_GTDIAGONALS;Pravidlo diagonál +TP_CROP_GTHARMMEANS1;Harmonický priemer 1 +TP_CROP_GTHARMMEANS2;Harmonický priemer 2 +TP_CROP_GTHARMMEANS3;Harmonický priemer 3 +TP_CROP_GTHARMMEANS4;Harmonický priemer 4 +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_DETAIL_AMOUNT;Množstvo +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_EQUALIZER_CONTRAST_MINUS;Kontrast- +TP_EQUALIZER_CONTRAST_PLUS;Kontrast+ +TP_EQUALIZER_FINEST;najjemnejšie +TP_EQUALIZER_LABEL;Vyrovnávač vlnky +TP_EQUALIZER_LARGEST;najhrubšie +TP_EQUALIZER_NEUTRAL;Neutrálne +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_FILEDLGFILTERANY;Všetky súbory +TP_ICM_FILEDLGFILTERICM;Súbory ICC profilu +TP_ICM_GAMMABEFOREINPUT;Profil aplikuje Gamu +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_LABCURVE_SATURATION;Sýtosť +TP_LENSGEOM_AUTOCROP;Automatické orezanie +TP_LENSGEOM_FILL;Automatické vyplnenie +TP_LENSGEOM_LABEL;Objektív/Geometria +TP_LUMACURVE_BLACKLEVEL;Čierna +TP_LUMACURVE_BRIGHTNESS;Jas +TP_LUMACURVE_COMPRHIGHLIGHTS;Kompresia najvyšších svetiel +TP_LUMACURVE_COMPRSHADOWS;Kompresia tieňov +TP_LUMACURVE_CONTRAST;Kontrast +TP_LUMACURVE_CURVEEDITOR;Krivka svietivosti +TP_LUMACURVE_LABEL;Krivka svietivosti +TP_PERSPECTIVE_HORIZONTAL;Horizontálne +TP_PERSPECTIVE_LABEL;Perspektíva +TP_PERSPECTIVE_VERTICAL;Vertikálne +TP_PREPROCESS_GREENEQUIL;Vyvažovanie zelenej +TP_PREPROCESS_HOTDEADPIXFILT;Použiť filter na horúce/mŕtve pixely +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_DMETHODBATCH;Dávka +TP_RAW_DMETHOD;Metóda +TP_RAW_FALSECOLOR;Kroky potlačenia chybných farieb +TP_RESIZE_BICUBICSF;Bikubická (Mäkšia) +TP_RESIZE_BICUBICSH;Bikubická (Ostrejšia) +TP_RESIZE_BICUBIC;Bikubická +TP_RESIZE_BILINEAR;Bilineárna +TP_RESIZE_DOWNSCALEB;Downscale (Lepšie) +TP_RESIZE_DOWNSCALEF;Downscale (Rýchlejšie) +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_AUTOCROP;Automatické orezanie +TP_ROTATE_DEGREE;Stupeň +TP_ROTATE_FILL;Výplň +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_CURVES;Curves +!CURVEEDITOR_CURVE;Curve +!CURVEEDITOR_MINMAXCPOINTS;Minima/Maxima control points +!CURVEEDITOR_TOOLTIPCOPY;Copy current curve to clipboard +!CURVEEDITOR_TOOLTIPPASTE;Paste curve from clipboard +!EDITWINDOW_TITLE;Image Edit +!EXIFFILTER_EXPOSURECOMPENSATION;Exposure Compensation (EV) +!EXIFFILTER_FILETYPE;File Type +!EXPORT_BYPASS_ALL;Select / Unselect All +!EXPORT_BYPASS_COLORDENOISE;Bypass Color denoise +!EXPORT_BYPASS_DEFRINGE;Bypass Defringe +!EXPORT_BYPASS_DIRPYRDENOISE;Bypass Noise Reduction +!EXPORT_BYPASS_DIRPYREQUALIZER;Bypass Contrast by Detail Levels +!EXPORT_BYPASS_LUMADENOISE;Bypass Luma denoise +!EXPORT_BYPASS_RAW_ALL_ENHANCE;Bypass Post Demosaic Artifact/Noise Reduction +!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 +!EXPORT_RESIZEMETHOD;Resize 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.\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\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_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_POPUPRANK;Rank +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!FILEBROWSER_QUERYHINT;Type a partial filename to search for or a comma-separated list.\nE.g. 1001,1004,1199 \n\nCtrl-F to focus to the Find text box.\nEnter to commence search.\nEsc to clear.\nShift-Esc to remove focus. +!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_SHOWRECENTLYSAVEDHINT;Show images recently saved.\nShortcut: Alt-7 +!FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show images not recently saved.\nShortcut: Alt-6 +!FILEBROWSER_SHOWUNCOLORHINT;Show images without Color label.\nShortcut: Alt-0 +!FILEBROWSER_UNRANK_TOOLTIP;Unrank\nShortcut: Shift-0 +!GENERAL_AUTO;Automatic +!GENERAL_CLOSE;Close +!GENERAL_FILE;File +!GENERAL_NONE;None +!GENERAL_WARNING;Warning +!HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar\nClick right mouse button on image preview to freeze/unfreeze +!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram +!HISTOGRAM_TOOLTIP_FULL;Toggle full (on) or scaled (off) 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;Lab - Chromaticity +!HISTORY_MSG_96;'a' Curve +!HISTORY_MSG_97;'b' Curve +!HISTORY_MSG_98;Demosaicing Method +!HISTORY_MSG_99;Hot/Dead pixel filter +!HISTORY_MSG_100;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;Resizing applies to +!HISTORY_MSG_111;Lab - Avoid color shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;Lab - Protection +!HISTORY_MSG_114;DCB Iterations +!HISTORY_MSG_115;False Color Suppression +!HISTORY_MSG_116;DCB Enhancement +!HISTORY_MSG_117;Raw Red CA Correction +!HISTORY_MSG_118;Raw Blue CA Correction +!HISTORY_MSG_119;Line Noise Filter +!HISTORY_MSG_120;Green Equilibration +!HISTORY_MSG_121;Raw Auto CA +!HISTORY_MSG_122;Dark Frame Auto Select +!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 Select +!HISTORY_MSG_128;Flat Field Blur Radius +!HISTORY_MSG_129;Flat Field Blur Type +!HISTORY_MSG_130;Auto Distorion +!HISTORY_MSG_131;Noise Reduction Luma +!HISTORY_MSG_132;Noise Reduction 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;Edges Sharpening +!HISTORY_MSG_147;ES - Luminance Only +!HISTORY_MSG_148;Microcontrast +!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_150;Post Demosaic Artifact/Noise Reduction +!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;'CC' curve +!HISTORY_MSG_169;'CH' curve +!HISTORY_MSG_170;Vib - Curve +!HISTORY_MSG_171;'LC' curve +!HISTORY_MSG_172;Lab - 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 tones protection +!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 pixels +!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;'CL' curve +!HISTORY_MSG_247;'LH' curve +!HISTORY_MSG_248;'HH' curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +!MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the Next image relative to image open in Editor\nShortcut: Shift-F4\n\nTo navigate to the Next image relative to thumbnail selected in File Browser\nShortcut: F4 +!MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the Previous image relative to image open in Editor\nShortcut: Shift-F3 \n\nTo navigate to the Previous image relative to thumbnail selected in File Browser\nShortcut: F3 +!MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronize the File Browser with the Editor to reveal the thumbnail of the currently open image, and clear filters in File Browser \nShortcut: x\n\nAs above, but without clearing filters in File Browser\nShortcut: y\n(Note that thumbnail of the open file 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\ndoesn't exist. Please set a correct path in the Preference window. +!MAIN_MSG_SETPATHFIRST;You have to set a target path first in Preferences\nin order to use this function! +!MAIN_MSG_WRITEFAILED;Failed to write\n\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_METADATA_TOOLTIP;Shortcut: Alt-m +!MAIN_TAB_RAW;Raw +!MAIN_TAB_RAW_TOOLTIP;Shortcut: Alt-r +!MAIN_TAB_TRANSFORM_TOOLTIP;Shortcut: Alt-t +!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 10-30%\n\nPreview is rendered slower with Focus Mask turned on. +!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_LAB_A_NA;a = n/a +!NAVIGATOR_LAB_A_VALUE;a = %1 +!NAVIGATOR_LAB_B_NA;b = n/a +!NAVIGATOR_LAB_B_VALUE;b = %1 +!NAVIGATOR_LAB_L_NA;L = n/a +!NAVIGATOR_LAB_L_VALUE;L = %1 +!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;CIE Color Appearance Model 2002 +!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_EVERYTHING;Everything +!PARTIALPASTE_FLATFIELDAUTOSELECT;Flat field auto selection +!PARTIALPASTE_FLATFIELDBLURRADIUS;Flat field blur radius +!PARTIALPASTE_FLATFIELDBLURTYPE;Flat field blur type +!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_GREENEQUIL;Green equilibration +!PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Apply hot/dead 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_ALLENHANCE;Post-demosaic artifact/noise reduction +!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 +!PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!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_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_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 scipts 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_DATEFORMATFRAME;Date Format +!PREFERENCES_DIRDARKFRAMES;Dark frames directory +!PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar (de-select for low resolution display) +!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_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;Output device's Yb luminance (%) +!PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogram in left panel +!PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Show embedded JPEG thumbnail if raw is unedited +!PREFERENCES_LANGAUTODETECT;Use OS language setting +!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_MULTITABDUALMON;Multiple Editor Tabs Mode (if available on second monitor) +!PREFERENCES_OVERWRITEOUTPUTFILE;Overwrite existing output files +!PREFERENCES_PANFACTORFRAME;Pan Rate Amplification +!PREFERENCES_PANFACTORLABEL;Factor +!PREFERENCES_RGBDTL_LABEL;Max number of threads for Noise Reduction +!PREFERENCES_RGBDTL_TOOLTIP;Noise Reduction requires a baseline of about 128MB RAM for a 10MPix image or 512MB for a 40MPix image, and additionally 128MB RAM per thread. The more threads run in parallel, the faster the computation. Leave the setting at "0" to automatically use as many threads as possible. +!PREFERENCES_SHOWEXPOSURECOMPENSATION;Append exposure compensation +!PREFERENCES_SHOWPROFILESELECTOR;Show processing profile selector +!PREFERENCES_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs +!PREFERENCES_SLIMUI;Slim interface +!PREFERENCES_SND_BATCHQUEUEDONE;Queue processing done +!PREFERENCES_SND_HELP;Either enter filepath or nothing (for no sound).\nOn Windows use "SystemDefault", "SystemAsterisk" etc. for system sounds.\nOn Linux use "complete", "window-attention" etc. for system sounds. +!PREFERENCES_SND_LNGEDITPROCDONE;Editor processing done +!PREFERENCES_SND_TRESHOLDSECS;after secs +!PREFERENCES_SQUAREDETAILWINDOW;Square detail window (faster) +!PREFERENCES_TAB_PERFORMANCE;Performance +!PREFERENCES_TAB_SOUND;Sounds +!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.) +!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_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing channel-mixer +!TP_BWMIX_BLUE;Blue +!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;Modify luminance in function of hue\nPay attention to extreme values that may cause artifacts +!TP_BWMIX_CYAN;Cyan +!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 simulate shots taken with a colored filter placed in front of the lens. Colored filters reduce transmission of specific range of colors and correspondingly affect their lightness. E.g. a Red filter darkens Blue skies. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_BLUE;Blue Channel +!TP_BWMIX_GAM_GREEN;Green Channel +!TP_BWMIX_GAM_RED;Red Channel +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each channel RGB +!TP_BWMIX_GREEN;Green +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MAGENTA;Magenta +!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 (filter, channel-mixer) to default +!TP_BWMIX_ORANGE;Orange +!TP_BWMIX_PURPLE;Purple +!TP_BWMIX_RED;Red +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all of the mixer options\nTotal displays the sum of RGB values actually applied:\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 (films, landscape, ...) or manual settings of channel-mixer +!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;Channel-Mixer absolute RGB +!TP_BWMIX_SET_RGBREL;Channel-Mixer relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Channel-Mixer absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Channel-Mixer 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_BWMIX_YELLOW;Yellow +!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) RT 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.\n 0=no effect 1=median 2=gaussian.\n\nThese artifacts are due to limitations of CIECAM02. Alternatively, adjust the image to avoid very dark shadows. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from Lab and RGB brightness +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from Lab and RGB colorfulness +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from Lab and RGB saturation +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from Lab 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 Lab and RGB contrast +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from Lab and RGB contrast +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L (Lab) 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 (Lab) 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 Lab values before CIECAM02 adjustments +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RT 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 (Lab) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in Lab 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 Lab and RGB lightness +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model\n\nWB [RT] + [output]:\nRT's white balance is used for the scene, CIECAM02 is set to D50, the output device's white balance is set in Preferences > Color Management\n\nWB [RT+CAT02] + [output]:\nRT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences +!TP_COLORAPP_RSTPRO;Red & skin tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin tones protection (sliders and curves) +!TP_COLORAPP_SHARPCIE;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe with Q/C +!TP_COLORAPP_SHARPCIE_TOOLTIP;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe will use CIECAM02 if enabled. +!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;Change tones and colors to take into account the viewing conditions of the output device\n\nAverage:\nAverage light environment (standard)\nThe image will not change\n\nDim:\nDim environment (TV)\nThe image will become slighty dark\n\nDark:\nDark environment (projector)\nThe image will become more dark\n\nExtremly Dark:\nExtremly dark environment (cutsheet)\nThe image will become very dark +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if source 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 Lab 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_CROP_GTEPASSPORT;Biometric Passport +!TP_CROP_GTFRAME;Frame +!TP_CROP_GTGRID;Grid +!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_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on gamma of the input color profile. Gamma of sRGB is assumed, thus if input image is in color profile of a different gamma, luminance noise reduction will vary. +!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_LDETAIL;Luminance Detail +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or Lab methods can be used.\n\nFor non-raw images Lab method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_PERF;RGB mode (raw images) +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGB;RGB +!TP_DISTORTION_AUTO;Auto Distortion Correction +!TP_DISTORTION_AUTO_TIP;(Exprimental) Correct lens distortion automatically for some cameras (Micro 4/3, some compact digital cameras, etc.) +!TP_EPD_EDGESTOPPING;Edge Stopping +!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 via Lab mode (standard) and CIECAM02 mode.\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_EXPOSCORR_LABEL;Raw White & Black Points +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggle execution of auto levels to automatically set parameter values based on image analysis\nEnable Highlight Reconstruction if necessary +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in auto level's 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 following section of the manual to learn how to achieve the best results with double curves:\nThe Toolbox > Exposure Tab > Exposure Panel > Tone Curve +!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_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!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_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 effect of this tool or some of its sub-component is only visible at 1:1 preview scale. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Rotation anchor point X: -100=left edge, 0=center, +100=right edge +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Rotation anchor point Y: -100=top edge, 0=center, +100=bottom edge +!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 automatic exposure +!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 blown 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 simple color matrix by dcraw, enhanced RawTherapee version (whichever is available based on camera model) or embedded in 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. Use only in special cases. +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. Result can be used for calibration purposes, 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;Can be used with the Chromaticity slider and the CC curve. +!TP_LENSPROFILE_FILEDLGFILTERLCP;Lens correction files +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;CA Correction +!TP_LENSPROFILE_USEDIST;Distortion correction +!TP_LENSPROFILE_USEVIGN;Vignetting correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset 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: 0=corners only, 50=halfway to center, 100=to center +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness: 0=rectangle, 50=fitted ellipse, 100=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. Higher = more, lower = less. +!TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Try to suppress hot and dead pixels +!TP_PREPROCESS_LABEL;Preprocessing +!TP_PREPROCESS_NO_FOUND;None found +!TP_RAWCACORR_CABLUE;Blue +!TP_RAWCACORR_CARED;Red +!TP_RAWEXPOS_BLACKONE;Black Level: Red +!TP_RAWEXPOS_BLACKS;Black Levels +!TP_RAWEXPOS_BLACKTHREE;Black Level: Green 2 +!TP_RAWEXPOS_BLACKTWO;Black Level: Blue +!TP_RAWEXPOS_BLACKZERO;Black Level: Green 1 (lead) +!TP_RAWEXPOS_LINEAR;White Point Correction +!TP_RAWEXPOS_PRESER;Highlight Preservation +!TP_RAWEXPOS_TWOGREEN;Link greens +!TP_RAW_ALLENHANCE;Post-Demosaic Artifact/Noise Reduction +!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 +!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_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 used 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_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 diff --git a/rtdata/languages/Suomi b/rtdata/languages/Suomi new file mode 100644 index 000000000..184a53b83 --- /dev/null +++ b/rtdata/languages/Suomi @@ -0,0 +1,1441 @@ +#01 2009-05-03 T. Kauppinen + +ADJUSTER_RESET_TO_DEFAULT;Palauta oletusasetukset +CURVEEDITOR_FILEDLGFILTERANY;Kaikki tiedostot +CURVEEDITOR_FILEDLGFILTERCURVE;Käyrätiedostot +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ä +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_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_SAVEAS;... +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_TAGGING;Tagging +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_LUMACURVE;Luminanssikäyrä +PARTIALPASTE_METAICMGROUP;Metatiedot ja ICM-profiili +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_BLINKCLIPPED;Välkytä leikkautuvia alueita +PREFERENCES_CACHECLEARALL;Tyhjennä kaikki +PREFERENCES_CACHECLEARPROFILES;Tyhjennä profiilit +PREFERENCES_CACHECLEARTHUMBS;Tyhjennä esikatselukuvat +PREFERENCES_CACHEFORMAT1;RawTherapee (nopeampi ja parempilaatuinen) +PREFERENCES_CACHEFORMAT2;JPEG (pienempi koko) +PREFERENCES_CACHEMAXENTRIES;Välimuistin koko +PREFERENCES_CACHEOPTS;Välimuistin asetukset +PREFERENCES_CACHETHUMBFORM;Välimuistin esikatselukuvien muoto +PREFERENCES_CACHETHUMBHEIGHT;Suurin esikatselukuvan korkeus +PREFERENCES_CLEARDLG_LINE1;Välimuistiä tyhjennetään +PREFERENCES_CLEARDLG_LINE2;Tämä voi kestää joitain sekunteja. +PREFERENCES_CLEARDLG_TITLE;Odota. +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_GTKTHEME;GTK oletus +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_FILEDLGFILTERANY;Kaikki tiedostot +PROFILEPANEL_FILEDLGFILTERPP;Profiilitiedostot +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... +PROGRESSDLG_LOADING;Kuvaa ladataan... +PROGRESSDLG_PROCESSING;Kuvaa käsitellään... +PROGRESSDLG_SAVING;Tiedostoa tallennetaan... +QINFO_ISO;ISO +QINFO_NOEXIF;EXIF-tietoja ei saatavilla. +SAVEDLG_FILEFORMAT;Tiedostomuoto +SAVEDLG_JPEGQUAL;JPEG laatu (suurempi luku, parempi laatu) +SAVEDLG_JPGFILTER;JPEG tiedostot +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_TIFFFILTER;TIFF tiedostot +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_DEGREE;astetta +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_COLORBOOST_ACHANNEL;a* +TP_COLORBOOST_AMOUNT;Määrä +TP_COLORBOOST_AVOIDCOLORCLIP;Vältä leikkautuminen +TP_COLORBOOST_BCHANNEL;b* +TP_COLORBOOST_CHANNEL;Kanava +TP_COLORBOOST_CHSEPARATE;säädä erikseen +TP_COLORBOOST_ENABLESATLIMITER;Estä kyllästyminen +TP_COLORBOOST_LABEL;Värikylläisyys +TP_COLORBOOST_SATLIMIT;Kyllästymisraja +TP_COLORDENOISE_EDGESENSITIVE;Reunaherkkä +TP_COLORDENOISE_EDGETOLERANCE;Reunan tunnistusherkkyys +TP_COLORDENOISE_LABEL;Värin kohinanvaimennus +TP_COLORDENOISE_RADIUS;Säde +TP_COLORSHIFT_BLUEYELLOW;sininen-keltainen +TP_COLORSHIFT_GREENMAGENTA;vihreä-punainen +TP_COLORSHIFT_LABEL;Värisävy +TP_CROP_DPI;Erottelutarkkuus (DPI): +TP_CROP_FIXRATIO;Pidä kuvasuhde: +TP_CROP_GTDIAGONALS;Kulmien puolittajat +TP_CROP_GTHARMMEANS1;Kultainen leikkaus 1 +TP_CROP_GTHARMMEANS2;Kultainen leikkaus 2 +TP_CROP_GTHARMMEANS3;Kultainen leikkaus 3 +TP_CROP_GTHARMMEANS4;Kultainen leikkaus 4 +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_FILEDLGFILTERANY;kaikki tiedostot +TP_ICM_FILEDLGFILTERICM;ICC-profiilitiedostot +TP_ICM_GAMMABEFOREINPUT;Käytä profiilin gammaa +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_LUMACURVE_BLACKLEVEL;Tummuus +TP_LUMACURVE_BRIGHTNESS;Kirkkaus +TP_LUMACURVE_COMPRHIGHLIGHTS;Vaaleiden alueiden vaimennus +TP_LUMACURVE_COMPRSHADOWS;Tummien alueiden vaimennus +TP_LUMACURVE_CONTRAST;Kontrasti +TP_LUMACURVE_CURVEEDITOR;Luminanssin käyrä +TP_LUMACURVE_LABEL;Luminanssi +TP_RAW_DMETHOD;Menetelmä +TP_RAW_FALSECOLOR;Värivääristymien eston määrä +TP_RESIZE_BICUBICSF;Bikuutiollinen (Pehmeämpi) +TP_RESIZE_BICUBICSH;Bikuutiollinen (Terävämpi) +TP_RESIZE_BICUBIC;Bikuutiollinen +TP_RESIZE_BILINEAR;Bilineaarinen +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_AUTOCROP;Aseta rajaus +TP_ROTATE_DEGREE;Astetta +TP_ROTATE_FILL;Suurenna/pienennä kuva automaattisesti +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_CURVES;Curves +!CURVEEDITOR_CURVE;Curve +!CURVEEDITOR_CUSTOM;Custom +!CURVEEDITOR_DARKS;Darks +!CURVEEDITOR_HIGHLIGHTS;Highlights +!CURVEEDITOR_LIGHTS;Lights +!CURVEEDITOR_MINMAXCPOINTS;Minima/Maxima control points +!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 +!EXIFFILTER_EXPOSURECOMPENSATION;Exposure Compensation (EV) +!EXIFFILTER_FILETYPE;File Type +!EXIFFILTER_METADATAFILTER;Enable Metadata Filters +!EXPORT_BYPASS_ALL;Select / Unselect All +!EXPORT_BYPASS_COLORDENOISE;Bypass Color denoise +!EXPORT_BYPASS_DEFRINGE;Bypass Defringe +!EXPORT_BYPASS_DIRPYRDENOISE;Bypass Noise Reduction +!EXPORT_BYPASS_DIRPYREQUALIZER;Bypass Contrast by Detail Levels +!EXPORT_BYPASS_LUMADENOISE;Bypass Luma denoise +!EXPORT_BYPASS_RAW_ALL_ENHANCE;Bypass Post Demosaic Artifact/Noise Reduction +!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 +!EXPORT_RESIZEMETHOD;Resize 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.\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\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_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_POPUPRANK;Rank +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!FILEBROWSER_QUERYHINT;Type a partial filename to search for or a comma-separated list.\nE.g. 1001,1004,1199 \n\nCtrl-F to focus to the Find text box.\nEnter to commence search.\nEsc to clear.\nShift-Esc to remove focus. +!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.\nShortcut: i\n\nShortcut in Single Editor Tab Mode: Alt-i +!FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show images recently saved.\nShortcut: Alt-7 +!FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show images not recently saved.\nShortcut: Alt-6 +!FILEBROWSER_SHOWUNCOLORHINT;Show images without Color label.\nShortcut: Alt-0 +!FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +!FILEBROWSER_UNRANK_TOOLTIP;Unrank\nShortcut: Shift-0 +!FILEBROWSER_USETEMPLATE;Use template: +!GENERAL_AFTER;After +!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\nClick right mouse button on image preview to freeze/unfreeze +!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram +!HISTOGRAM_TOOLTIP_FULL;Toggle full (on) or scaled (off) 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;Lab - Chromaticity +!HISTORY_MSG_96;'a' Curve +!HISTORY_MSG_97;'b' Curve +!HISTORY_MSG_98;Demosaicing Method +!HISTORY_MSG_99;Hot/Dead pixel filter +!HISTORY_MSG_100;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;Resizing applies to +!HISTORY_MSG_111;Lab - Avoid color shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;Lab - Protection +!HISTORY_MSG_114;DCB Iterations +!HISTORY_MSG_115;False Color Suppression +!HISTORY_MSG_116;DCB Enhancement +!HISTORY_MSG_117;Raw Red CA Correction +!HISTORY_MSG_118;Raw Blue CA Correction +!HISTORY_MSG_119;Line Noise Filter +!HISTORY_MSG_120;Green Equilibration +!HISTORY_MSG_121;Raw Auto CA +!HISTORY_MSG_122;Dark Frame Auto Select +!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 Select +!HISTORY_MSG_128;Flat Field Blur Radius +!HISTORY_MSG_129;Flat Field Blur Type +!HISTORY_MSG_130;Auto Distorion +!HISTORY_MSG_131;Noise Reduction Luma +!HISTORY_MSG_132;Noise Reduction 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;Edges Sharpening +!HISTORY_MSG_147;ES - Luminance Only +!HISTORY_MSG_148;Microcontrast +!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_150;Post Demosaic Artifact/Noise Reduction +!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;'CC' curve +!HISTORY_MSG_169;'CH' curve +!HISTORY_MSG_170;Vib - Curve +!HISTORY_MSG_171;'LC' curve +!HISTORY_MSG_172;Lab - 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 tones protection +!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 pixels +!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;'CL' curve +!HISTORY_MSG_247;'LH' curve +!HISTORY_MSG_248;'HH' curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +!MAIN_BUTTON_FULLSCREEN;Fullscreen +!MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the Next image relative to image open in Editor\nShortcut: Shift-F4\n\nTo navigate to the Next image relative to thumbnail selected in File Browser\nShortcut: F4 +!MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the Previous image relative to image open in Editor\nShortcut: Shift-F3 \n\nTo navigate to the Previous image relative to thumbnail selected in File Browser\nShortcut: F3 +!MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronize the File Browser with the Editor to reveal the thumbnail of the currently open image, and clear filters in File Browser \nShortcut: x\n\nAs above, but without clearing filters in File Browser\nShortcut: y\n(Note that thumbnail of the open file 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\ndoesn't exist. Please set a correct path in the Preference window. +!MAIN_MSG_SETPATHFIRST;You have to set a target path first in Preferences\nin order to use this function! +!MAIN_MSG_WRITEFAILED;Failed to write\n\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_METADATA_TOOLTIP;Shortcut: Alt-m +!MAIN_TAB_RAW;Raw +!MAIN_TAB_RAW_TOOLTIP;Shortcut: Alt-r +!MAIN_TAB_TRANSFORM_TOOLTIP;Shortcut: Alt-t +!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 10-30%\n\nPreview is rendered slower with Focus Mask turned on. +!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_NA;B = n/a +!NAVIGATOR_B_VALUE;B = %1 +!NAVIGATOR_G_NA;G = n/a +!NAVIGATOR_G_VALUE;G = %1 +!NAVIGATOR_H_NA;H = n/a +!NAVIGATOR_H_VALUE;H = %1 +!NAVIGATOR_LAB_A_NA;a = n/a +!NAVIGATOR_LAB_A_VALUE;a = %1 +!NAVIGATOR_LAB_B_NA;b = n/a +!NAVIGATOR_LAB_B_VALUE;b = %1 +!NAVIGATOR_LAB_L_NA;L = n/a +!NAVIGATOR_LAB_L_VALUE;L = %1 +!NAVIGATOR_R_NA;R = n/a +!NAVIGATOR_R_VALUE;R = %1 +!NAVIGATOR_S_NA;S = n/a +!NAVIGATOR_S_VALUE;S = %1 +!NAVIGATOR_V_NA;V = n/a +!NAVIGATOR_V_VALUE;V = %1 +!NAVIGATOR_XY_FULL;Width = %1, Height = %2 +!NAVIGATOR_XY_NA;x = n/a, y = n/a +!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;CIE Color Appearance Model 2002 +!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_EVERYTHING;Everything +!PARTIALPASTE_FLATFIELDAUTOSELECT;Flat field auto selection +!PARTIALPASTE_FLATFIELDBLURRADIUS;Flat field blur radius +!PARTIALPASTE_FLATFIELDBLURTYPE;Flat field blur type +!PARTIALPASTE_FLATFIELDFILE;Flat field file +!PARTIALPASTE_GRADIENT;Graduated filter +!PARTIALPASTE_HSVEQUALIZER;HSV equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!PARTIALPASTE_LABCURVE;Lab adjustments +!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_PERSPECTIVE;Perspective +!PARTIALPASTE_PREPROCESS_GREENEQUIL;Green equilibration +!PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Apply hot/dead 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_ALLENHANCE;Post-demosaic artifact/noise reduction +!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 +!PREFERENCES_ADD;Add +!PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!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_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_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 scipts 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_DATEFORMATFRAME;Date Format +!PREFERENCES_DIRDARKFRAMES;Dark frames directory +!PREFERENCES_EDITORLAYOUT;Editor Layout +!PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar (de-select for low resolution display) +!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_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;Output device's Yb luminance (%) +!PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogram in left panel +!PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Show embedded JPEG thumbnail if raw is unedited +!PREFERENCES_LANGAUTODETECT;Use OS language setting +!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_MULTITABDUALMON;Multiple Editor Tabs Mode (if available on second monitor) +!PREFERENCES_MULTITAB;Multiple Editor Tabs Mode +!PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails +!PREFERENCES_OVERWRITEOUTPUTFILE;Overwrite existing output files +!PREFERENCES_PANFACTORFRAME;Pan Rate Amplification +!PREFERENCES_PANFACTORLABEL;Factor +!PREFERENCES_PROPERTY;Property +!PREFERENCES_RGBDTL_LABEL;Max number of threads for Noise Reduction +!PREFERENCES_RGBDTL_TOOLTIP;Noise Reduction requires a baseline of about 128MB RAM for a 10MPix image or 512MB for a 40MPix image, and additionally 128MB RAM per thread. The more threads run in parallel, the faster the computation. Leave the setting at "0" to automatically use as many threads as possible. +!PREFERENCES_SELECTFONT;Select font +!PREFERENCES_SET;Set +!PREFERENCES_SHOWEXPOSURECOMPENSATION;Append exposure compensation +!PREFERENCES_SHOWPROFILESELECTOR;Show processing profile selector +!PREFERENCES_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs +!PREFERENCES_SINGLETAB;Single Editor Tab Mode +!PREFERENCES_SLIMUI;Slim interface +!PREFERENCES_SND_BATCHQUEUEDONE;Queue processing done +!PREFERENCES_SND_HELP;Either enter filepath or nothing (for no sound).\nOn Windows use "SystemDefault", "SystemAsterisk" etc. for system sounds.\nOn Linux use "complete", "window-attention" etc. for system sounds. +!PREFERENCES_SND_LNGEDITPROCDONE;Editor processing done +!PREFERENCES_SND_TRESHOLDSECS;after secs +!PREFERENCES_SQUAREDETAILWINDOW;Square detail window (faster) +!PREFERENCES_TAB_PERFORMANCE;Performance +!PREFERENCES_TAB_SOUND;Sounds +!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_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_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing channel-mixer +!TP_BWMIX_BLUE;Blue +!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;Modify luminance in function of hue\nPay attention to extreme values that may cause artifacts +!TP_BWMIX_CYAN;Cyan +!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 simulate shots taken with a colored filter placed in front of the lens. Colored filters reduce transmission of specific range of colors and correspondingly affect their lightness. E.g. a Red filter darkens Blue skies. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_BLUE;Blue Channel +!TP_BWMIX_GAM_GREEN;Green Channel +!TP_BWMIX_GAM_RED;Red Channel +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each channel RGB +!TP_BWMIX_GREEN;Green +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MAGENTA;Magenta +!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 (filter, channel-mixer) to default +!TP_BWMIX_ORANGE;Orange +!TP_BWMIX_PURPLE;Purple +!TP_BWMIX_RED;Red +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all of the mixer options\nTotal displays the sum of RGB values actually applied:\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 (films, landscape, ...) or manual settings of channel-mixer +!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;Channel-Mixer absolute RGB +!TP_BWMIX_SET_RGBREL;Channel-Mixer relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Channel-Mixer absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Channel-Mixer 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_BWMIX_YELLOW;Yellow +!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) RT 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.\n 0=no effect 1=median 2=gaussian.\n\nThese artifacts are due to limitations of CIECAM02. Alternatively, adjust the image to avoid very dark shadows. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from Lab and RGB brightness +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from Lab and RGB colorfulness +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from Lab and RGB saturation +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from Lab 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 Lab and RGB contrast +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from Lab and RGB contrast +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L (Lab) 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 (Lab) 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 Lab values before CIECAM02 adjustments +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RT 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 (Lab) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in Lab 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 Lab and RGB lightness +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model\n\nWB [RT] + [output]:\nRT's white balance is used for the scene, CIECAM02 is set to D50, the output device's white balance is set in Preferences > Color Management\n\nWB [RT+CAT02] + [output]:\nRT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences +!TP_COLORAPP_RSTPRO;Red & skin tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin tones protection (sliders and curves) +!TP_COLORAPP_SHARPCIE;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe with Q/C +!TP_COLORAPP_SHARPCIE_TOOLTIP;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe will use CIECAM02 if enabled. +!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;Change tones and colors to take into account the viewing conditions of the output device\n\nAverage:\nAverage light environment (standard)\nThe image will not change\n\nDim:\nDim environment (TV)\nThe image will become slighty dark\n\nDark:\nDark environment (projector)\nThe image will become more dark\n\nExtremly Dark:\nExtremly dark environment (cutsheet)\nThe image will become very dark +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if source 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 Lab 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_CROP_GTEPASSPORT;Biometric Passport +!TP_CROP_GTFRAME;Frame +!TP_CROP_GTGRID;Grid +!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_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_CHROMA;Chrominance - Master +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on gamma of the input color profile. Gamma of sRGB is assumed, thus if input image is in color profile of a different gamma, luminance noise reduction will vary. +!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_LAB;Lab +!TP_DIRPYRDENOISE_LDETAIL;Luminance Detail +!TP_DIRPYRDENOISE_LUMA;Luminance +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or Lab methods can be used.\n\nFor non-raw images Lab method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_PERF;RGB mode (raw images) +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGB;RGB +!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_THRESHOLD;Threshold +!TP_DISTORTION_AUTO;Auto Distortion Correction +!TP_DISTORTION_AUTO_TIP;(Exprimental) Correct lens distortion automatically for some cameras (Micro 4/3, some compact digital cameras, etc.) +!TP_EPD_EDGESTOPPING;Edge Stopping +!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 via Lab mode (standard) and CIECAM02 mode.\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_EXPOSCORR_LABEL;Raw White & Black Points +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggle execution of auto levels to automatically set parameter values based on image analysis\nEnable Highlight Reconstruction if necessary +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in auto level's 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 following section of the manual to learn how to achieve the best results with double curves:\nThe Toolbox > Exposure Tab > Exposure Panel > Tone Curve +!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_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!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_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 effect of this tool or some of its sub-component is only visible at 1:1 preview scale. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Rotation anchor point X: -100=left edge, 0=center, +100=right edge +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Rotation anchor point Y: -100=top edge, 0=center, +100=bottom edge +!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 automatic exposure +!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 blown 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 simple color matrix by dcraw, enhanced RawTherapee version (whichever is available based on camera model) or embedded in 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. Use only in special cases. +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. Result can be used for calibration purposes, 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;Lab 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;Can be used with the Chromaticity slider and the CC curve. +!TP_LENSGEOM_AUTOCROP;Auto Crop +!TP_LENSGEOM_FILL;Auto fill +!TP_LENSGEOM_LABEL;Lens / Geometry +!TP_LENSPROFILE_FILEDLGFILTERLCP;Lens correction files +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;CA Correction +!TP_LENSPROFILE_USEDIST;Distortion correction +!TP_LENSPROFILE_USEVIGN;Vignetting correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset 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: 0=corners only, 50=halfway to center, 100=to center +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness: 0=rectangle, 50=fitted ellipse, 100=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. Higher = more, lower = less. +!TP_PREPROCESS_GREENEQUIL;Green Equilibration +!TP_PREPROCESS_HOTDEADPIXFILT;Hot/Dead pixel filter +!TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Try to suppress hot and dead 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_BLACKONE;Black Level: Red +!TP_RAWEXPOS_BLACKS;Black Levels +!TP_RAWEXPOS_BLACKTHREE;Black Level: Green 2 +!TP_RAWEXPOS_BLACKTWO;Black Level: Blue +!TP_RAWEXPOS_BLACKZERO;Black Level: Green 1 (lead) +!TP_RAWEXPOS_LINEAR;White Point Correction +!TP_RAWEXPOS_PRESER;Highlight Preservation +!TP_RAWEXPOS_TWOGREEN;Link greens +!TP_RAW_ALLENHANCE;Post-Demosaic Artifact/Noise Reduction +!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 +!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_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 used 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_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_ZOOMFITSCREEN;Fit 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..b1ee0653a --- /dev/null +++ b/rtdata/languages/Swedish @@ -0,0 +1,1395 @@ +#01 2008-01-22 Emil Ericsson +#02 2010-2013 Updated by Johan Thor +#04 2014-01-06 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_FILEDLGFILTERANY;Vilka filer som helst +CURVEEDITOR_FILEDLGFILTERCURVE;Kurvfiler +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: +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_COLORDENOISE;Förbigå färgbrusreducering +EXPORT_BYPASS_DEFRINGE;Förbigå överstrålning +EXPORT_BYPASS_DIRPYRDENOISE;Förbigå brusreducering +EXPORT_BYPASS_DIRPYREQUALIZER;Förbigå kontrast genom detaljnivåer +EXPORT_BYPASS_LUMADENOISE;Förbigå luminansbrusreducering +EXPORT_BYPASS_RAW_ALL_ENHANCE;Förbigå efter-demosaic artefakt- och brusreducering +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 +EXPORT_RESIZEMETHOD;Metod för storleksändring +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_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_USETEMPLATE;Använd förinställning: +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_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_TAGGING;Etiketter +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_B_NA;B = - +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_G_NA;G = - +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_H_NA;H = - +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_LAB_A_NA;A = - +NAVIGATOR_LAB_A_VALUE;A = %1 +NAVIGATOR_LAB_B_NA;B = - +NAVIGATOR_LAB_B_VALUE;B = %1 +NAVIGATOR_LAB_L_NA;L = - +NAVIGATOR_LAB_L_VALUE;L = %1 +NAVIGATOR_R_NA;R = - +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_S_NA;S = - +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_NA;V = - +NAVIGATOR_V_VALUE;V = %1 +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 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. +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_METAICMGROUP;Metadata/ICM inställningar +PARTIALPASTE_PCVIGNETTE;Vinjetteringsfilter +PARTIALPASTE_PERSPECTIVE;Perspektiv +PARTIALPASTE_PREPROCESS_GREENEQUIL;Grönbalansering +PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Tillämpa het- och dödpixelfilter +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_ALLENHANCE;Applicera reducering av artefakter och brus efter demosaicing +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_BLINKCLIPPED;Blinka med klippta områden +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_DATEFORMATFRAME;Datumformat +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_GTKTHEME;GTK-standard +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_PANFACTORFRAME;Förstärkning av panoreringstakten +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_SHOWPROFILESELECTOR;Visa profilväljaren +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_SQUAREDETAILWINDOW;Kvadratiskt detaljfönster (snabbare) +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_FILEDLGFILTERANY;Vilka filer som helst +PROFILEPANEL_FILEDLGFILTERPP;Efterbehandlingsprofiler +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_JPGFILTER;JPEG-filer +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_TIFFFILTER;TIFF-filer +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_AUTOCH;Auto +TP_BWMIX_AUTOCH_TIP;Beräkna värden som optimerar kanalmixern +TP_BWMIX_BLUE;Blå +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_CYAN;Cyan +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-Gull +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_BLUE;Blå kanal +TP_BWMIX_GAM_GREEN;Grön kanal +TP_BWMIX_GAM_RED;Röd kanal +TP_BWMIX_GAM_TOOLTIP;Korrigera gamma för varje kanal i RGB +TP_BWMIX_GREEN;Grön +TP_BWMIX_LABEL;Svartvitt +TP_BWMIX_MAGENTA;Magenta +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_ORANGE;Orange +TP_BWMIX_PURPLE;Lila +TP_BWMIX_RED;Röd +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_BWMIX_YELLOW;Gul +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_GTHARMMEANS1;Harmoniskt medel 1 +TP_CROP_GTHARMMEANS2;Harmoniskt medel 2 +TP_CROP_GTHARMMEANS3;Harmoniskt medel 3 +TP_CROP_GTHARMMEANS4;Harmoniskt medel 4 +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_PERF;RGB-läge (råfiler) +TP_DIRPYRDENOISE_RED;Krominans - Röd-Grön +TP_DIRPYRDENOISE_RGB;RGB +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_THRESHOLD;Tröskelvärde +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_EXPOSCORR_LABEL;Vit- och svartpunktskorrigering, råformat +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_FILEDLGFILTERANY;Vilka filer som helst +TP_ICM_FILEDLGFILTERICM;Färgprofiler +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_ENABLESATLIMITER;Slå på mättnadsbegränsare +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_FILEDLGFILTERLCP;Objektivkorrigeringsfil +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_HOTDEADPIXFILT;Filtrera heta- och döda pixlar +TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Försöker att ta bort heta och döda pixlar i bilden +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_BLACKONE;Svartpunktsnivå: Röd +TP_RAWEXPOS_BLACKS;Svartpunktsnivåer +TP_RAWEXPOS_BLACKTHREE;Svartpunktsnivå: Grön 2 +TP_RAWEXPOS_BLACKTWO;Svartpunktsnivå: Blå +TP_RAWEXPOS_BLACKZERO;Svartpunktsnivå: Grön 1 (ledaren) +TP_RAWEXPOS_LINEAR;Vitpunktskorrigering +TP_RAWEXPOS_PRESER;Bevara högdagrar +TP_RAWEXPOS_TWOGREEN;Två gröna tillsammans +TP_RAW_ALLENHANCE;Reducering av artefakter och brus efter demosaicing +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_BICUBICSF;Bikubisk (Mjukare) +TP_RESIZE_BICUBICSH;Bikubisk (Skarpare) +TP_RESIZE_BICUBIC;Bikubisk +TP_RESIZE_BILINEAR;Bilinjär +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: - + diff --git a/rtdata/languages/Turkish b/rtdata/languages/Turkish new file mode 100644 index 000000000..fc51ff580 --- /dev/null +++ b/rtdata/languages/Turkish @@ -0,0 +1,1440 @@ +#01 2008-03-02 Oguz + +ADJUSTER_RESET_TO_DEFAULT;Varsayılana dön +CURVEEDITOR_FILEDLGFILTERANY;Bütün dosyalar +CURVEEDITOR_FILEDLGFILTERCURVE;Eğri dosyaları +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 +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_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_SAVEAS;... olarak +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_TAGGING;Tagging +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_LUMACURVE;Luminance curve +PARTIALPASTE_METAICMGROUP;Metadata/ICM settings +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_BLINKCLIPPED;Kırpılan alanlar yanıp-sönsün +PREFERENCES_CACHECLEARALL;Clear All +PREFERENCES_CACHECLEARPROFILES;Clear Profiles +PREFERENCES_CACHECLEARTHUMBS;Clear Thumbnails +PREFERENCES_CACHEFORMAT1;Proprietary (faster and better quality) +PREFERENCES_CACHEFORMAT2;JPEG (smaller disk footprint) +PREFERENCES_CACHEMAXENTRIES;Maximal Number of Cache Entries +PREFERENCES_CACHEOPTS;Cache Options +PREFERENCES_CACHETHUMBFORM;Cache Thumbnail Format +PREFERENCES_CACHETHUMBHEIGHT;Maximal Thumbnail Height +PREFERENCES_CLEARDLG_LINE1;Clearing cache +PREFERENCES_CLEARDLG_LINE2;This may take a few seconds. +PREFERENCES_CLEARDLG_TITLE;Please wait +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_GTKTHEME;GTK default +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_FILEDLGFILTERANY;Bütün dosyalar +PROFILEPANEL_FILEDLGFILTERPP;Art-işleme profilleri +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... +PROGRESSDLG_LOADING;Loading file... +PROGRESSDLG_PROCESSING;Processing image... +PROGRESSDLG_SAVING;Saving file... +QINFO_ISO;ISO +QINFO_NOEXIF;Exif bilgisi yok. +SAVEDLG_FILEFORMAT;Dosya biçimi +SAVEDLG_JPEGQUAL;JPEG kalitesi +SAVEDLG_JPGFILTER;JPEG dosyaları +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_TIFFFILTER;TIFF dosyaları +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_DEGREE;açı: +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_COLORBOOST_ACHANNEL;"a" kanalı +TP_COLORBOOST_AMOUNT;Miktar +TP_COLORBOOST_AVOIDCOLORCLIP;Renk kırpılasını önle +TP_COLORBOOST_BCHANNEL;"b" kanalı +TP_COLORBOOST_CHANNEL;Kanal +TP_COLORBOOST_CHSEPARATE;ayrık +TP_COLORBOOST_ENABLESATLIMITER;Doygunluk sınırlamayı etkinleştir +TP_COLORBOOST_LABEL;Renk iteleme +TP_COLORBOOST_SATLIMIT;Doygunluk sınırı +TP_COLORDENOISE_EDGESENSITIVE;Kenar duyarlı +TP_COLORDENOISE_EDGETOLERANCE;Kenar payı +TP_COLORDENOISE_LABEL;Renk gürültüsü azaltma +TP_COLORDENOISE_RADIUS;Çap +TP_COLORSHIFT_BLUEYELLOW;Mavi-sarı +TP_COLORSHIFT_GREENMAGENTA;Yeşil-macenta +TP_COLORSHIFT_LABEL;Renk kayması +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;En-boy oranını düzelt: +TP_CROP_GTDIAGONALS;Çaprazlar kuralı +TP_CROP_GTHARMMEANS1;Harmonik ortalamalar 1 +TP_CROP_GTHARMMEANS2;Harmonik ortalamalar 2 +TP_CROP_GTHARMMEANS3;Harmonik ortalamalar 3 +TP_CROP_GTHARMMEANS4;Harmonik ortalamalar 4 +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_FILEDLGFILTERANY;Bütün dosyalar +TP_ICM_FILEDLGFILTERICM;ICC profil dosyaları +TP_ICM_GAMMABEFOREINPUT;Profile applies Gamma +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_LUMACURVE_BLACKLEVEL;Siyah +TP_LUMACURVE_BRIGHTNESS;Parlaklık +TP_LUMACURVE_COMPRHIGHLIGHTS;Parıltı sıkıştırma +TP_LUMACURVE_COMPRSHADOWS;Karaltı sıkıştırma +TP_LUMACURVE_CONTRAST;Zıtlık +TP_LUMACURVE_CURVEEDITOR;Aydınlık eğrisi +TP_LUMACURVE_LABEL;Aydınlık eğrisi +TP_RAW_DMETHOD;Yöntem +TP_RAW_FALSECOLOR;Hatalı-renk bastırma değerleri +TP_RESIZE_BICUBICSF;Bikübik (yumuşak) +TP_RESIZE_BICUBICSH;Bikübik (keskin) +TP_RESIZE_BICUBIC;Bikübik +TP_RESIZE_BILINEAR;Çift-doğrusal +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_AUTOCROP;Otomatik kırpma +TP_ROTATE_DEGREE;Açı +TP_ROTATE_FILL;Doldur +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_CURVES;Curves +!CURVEEDITOR_CURVE;Curve +!CURVEEDITOR_CUSTOM;Custom +!CURVEEDITOR_DARKS;Darks +!CURVEEDITOR_HIGHLIGHTS;Highlights +!CURVEEDITOR_LIGHTS;Lights +!CURVEEDITOR_MINMAXCPOINTS;Minima/Maxima control points +!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 +!EXIFFILTER_EXPOSURECOMPENSATION;Exposure Compensation (EV) +!EXIFFILTER_FILETYPE;File Type +!EXIFFILTER_METADATAFILTER;Enable Metadata Filters +!EXPORT_BYPASS_ALL;Select / Unselect All +!EXPORT_BYPASS_COLORDENOISE;Bypass Color denoise +!EXPORT_BYPASS_DEFRINGE;Bypass Defringe +!EXPORT_BYPASS_DIRPYRDENOISE;Bypass Noise Reduction +!EXPORT_BYPASS_DIRPYREQUALIZER;Bypass Contrast by Detail Levels +!EXPORT_BYPASS_LUMADENOISE;Bypass Luma denoise +!EXPORT_BYPASS_RAW_ALL_ENHANCE;Bypass Post Demosaic Artifact/Noise Reduction +!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 +!EXPORT_RESIZEMETHOD;Resize 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.\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\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_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_POPUPRANK;Rank +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!FILEBROWSER_QUERYHINT;Type a partial filename to search for or a comma-separated list.\nE.g. 1001,1004,1199 \n\nCtrl-F to focus to the Find text box.\nEnter to commence search.\nEsc to clear.\nShift-Esc to remove focus. +!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.\nShortcut: i\n\nShortcut in Single Editor Tab Mode: Alt-i +!FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show images recently saved.\nShortcut: Alt-7 +!FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show images not recently saved.\nShortcut: Alt-6 +!FILEBROWSER_SHOWUNCOLORHINT;Show images without Color label.\nShortcut: Alt-0 +!FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +!FILEBROWSER_UNRANK_TOOLTIP;Unrank\nShortcut: Shift-0 +!FILEBROWSER_USETEMPLATE;Use template: +!GENERAL_AFTER;After +!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\nClick right mouse button on image preview to freeze/unfreeze +!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram +!HISTOGRAM_TOOLTIP_FULL;Toggle full (on) or scaled (off) 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;Lab - Chromaticity +!HISTORY_MSG_96;'a' Curve +!HISTORY_MSG_97;'b' Curve +!HISTORY_MSG_98;Demosaicing Method +!HISTORY_MSG_99;Hot/Dead pixel filter +!HISTORY_MSG_100;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;Resizing applies to +!HISTORY_MSG_111;Lab - Avoid color shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;Lab - Protection +!HISTORY_MSG_114;DCB Iterations +!HISTORY_MSG_115;False Color Suppression +!HISTORY_MSG_116;DCB Enhancement +!HISTORY_MSG_117;Raw Red CA Correction +!HISTORY_MSG_118;Raw Blue CA Correction +!HISTORY_MSG_119;Line Noise Filter +!HISTORY_MSG_120;Green Equilibration +!HISTORY_MSG_121;Raw Auto CA +!HISTORY_MSG_122;Dark Frame Auto Select +!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 Select +!HISTORY_MSG_128;Flat Field Blur Radius +!HISTORY_MSG_129;Flat Field Blur Type +!HISTORY_MSG_130;Auto Distorion +!HISTORY_MSG_131;Noise Reduction Luma +!HISTORY_MSG_132;Noise Reduction 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;Edges Sharpening +!HISTORY_MSG_147;ES - Luminance Only +!HISTORY_MSG_148;Microcontrast +!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_150;Post Demosaic Artifact/Noise Reduction +!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;'CC' curve +!HISTORY_MSG_169;'CH' curve +!HISTORY_MSG_170;Vib - Curve +!HISTORY_MSG_171;'LC' curve +!HISTORY_MSG_172;Lab - 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 tones protection +!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 pixels +!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;'CL' curve +!HISTORY_MSG_247;'LH' curve +!HISTORY_MSG_248;'HH' curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +!MAIN_BUTTON_FULLSCREEN;Fullscreen +!MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the Next image relative to image open in Editor\nShortcut: Shift-F4\n\nTo navigate to the Next image relative to thumbnail selected in File Browser\nShortcut: F4 +!MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the Previous image relative to image open in Editor\nShortcut: Shift-F3 \n\nTo navigate to the Previous image relative to thumbnail selected in File Browser\nShortcut: F3 +!MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronize the File Browser with the Editor to reveal the thumbnail of the currently open image, and clear filters in File Browser \nShortcut: x\n\nAs above, but without clearing filters in File Browser\nShortcut: y\n(Note that thumbnail of the open file 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\ndoesn't exist. Please set a correct path in the Preference window. +!MAIN_MSG_SETPATHFIRST;You have to set a target path first in Preferences\nin order to use this function! +!MAIN_MSG_WRITEFAILED;Failed to write\n\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_METADATA_TOOLTIP;Shortcut: Alt-m +!MAIN_TAB_RAW;Raw +!MAIN_TAB_RAW_TOOLTIP;Shortcut: Alt-r +!MAIN_TAB_TRANSFORM_TOOLTIP;Shortcut: Alt-t +!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 10-30%\n\nPreview is rendered slower with Focus Mask turned on. +!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_NA;B = n/a +!NAVIGATOR_B_VALUE;B = %1 +!NAVIGATOR_G_NA;G = n/a +!NAVIGATOR_G_VALUE;G = %1 +!NAVIGATOR_H_NA;H = n/a +!NAVIGATOR_H_VALUE;H = %1 +!NAVIGATOR_LAB_A_NA;a = n/a +!NAVIGATOR_LAB_A_VALUE;a = %1 +!NAVIGATOR_LAB_B_NA;b = n/a +!NAVIGATOR_LAB_B_VALUE;b = %1 +!NAVIGATOR_LAB_L_NA;L = n/a +!NAVIGATOR_LAB_L_VALUE;L = %1 +!NAVIGATOR_R_NA;R = n/a +!NAVIGATOR_R_VALUE;R = %1 +!NAVIGATOR_S_NA;S = n/a +!NAVIGATOR_S_VALUE;S = %1 +!NAVIGATOR_V_NA;V = n/a +!NAVIGATOR_V_VALUE;V = %1 +!NAVIGATOR_XY_FULL;Width = %1, Height = %2 +!NAVIGATOR_XY_NA;x = n/a, y = n/a +!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;CIE Color Appearance Model 2002 +!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_EVERYTHING;Everything +!PARTIALPASTE_FLATFIELDAUTOSELECT;Flat field auto selection +!PARTIALPASTE_FLATFIELDBLURRADIUS;Flat field blur radius +!PARTIALPASTE_FLATFIELDBLURTYPE;Flat field blur type +!PARTIALPASTE_FLATFIELDFILE;Flat field file +!PARTIALPASTE_GRADIENT;Graduated filter +!PARTIALPASTE_HSVEQUALIZER;HSV equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!PARTIALPASTE_LABCURVE;Lab adjustments +!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_PERSPECTIVE;Perspective +!PARTIALPASTE_PREPROCESS_GREENEQUIL;Green equilibration +!PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Apply hot/dead 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_ALLENHANCE;Post-demosaic artifact/noise reduction +!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 +!PREFERENCES_ADD;Add +!PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!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_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_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 scipts 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_DATEFORMATFRAME;Date Format +!PREFERENCES_DIRDARKFRAMES;Dark frames directory +!PREFERENCES_EDITORLAYOUT;Editor Layout +!PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar (de-select for low resolution display) +!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_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;Output device's Yb luminance (%) +!PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogram in left panel +!PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Show embedded JPEG thumbnail if raw is unedited +!PREFERENCES_LANGAUTODETECT;Use OS language setting +!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_MULTITABDUALMON;Multiple Editor Tabs Mode (if available on second monitor) +!PREFERENCES_MULTITAB;Multiple Editor Tabs Mode +!PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails +!PREFERENCES_OVERWRITEOUTPUTFILE;Overwrite existing output files +!PREFERENCES_PANFACTORFRAME;Pan Rate Amplification +!PREFERENCES_PANFACTORLABEL;Factor +!PREFERENCES_PROPERTY;Property +!PREFERENCES_RGBDTL_LABEL;Max number of threads for Noise Reduction +!PREFERENCES_RGBDTL_TOOLTIP;Noise Reduction requires a baseline of about 128MB RAM for a 10MPix image or 512MB for a 40MPix image, and additionally 128MB RAM per thread. The more threads run in parallel, the faster the computation. Leave the setting at "0" to automatically use as many threads as possible. +!PREFERENCES_SELECTFONT;Select font +!PREFERENCES_SET;Set +!PREFERENCES_SHOWEXPOSURECOMPENSATION;Append exposure compensation +!PREFERENCES_SHOWPROFILESELECTOR;Show processing profile selector +!PREFERENCES_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs +!PREFERENCES_SINGLETAB;Single Editor Tab Mode +!PREFERENCES_SLIMUI;Slim interface +!PREFERENCES_SND_BATCHQUEUEDONE;Queue processing done +!PREFERENCES_SND_HELP;Either enter filepath or nothing (for no sound).\nOn Windows use "SystemDefault", "SystemAsterisk" etc. for system sounds.\nOn Linux use "complete", "window-attention" etc. for system sounds. +!PREFERENCES_SND_LNGEDITPROCDONE;Editor processing done +!PREFERENCES_SND_TRESHOLDSECS;after secs +!PREFERENCES_SQUAREDETAILWINDOW;Square detail window (faster) +!PREFERENCES_TAB_PERFORMANCE;Performance +!PREFERENCES_TAB_SOUND;Sounds +!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_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_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing channel-mixer +!TP_BWMIX_BLUE;Blue +!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;Modify luminance in function of hue\nPay attention to extreme values that may cause artifacts +!TP_BWMIX_CYAN;Cyan +!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 simulate shots taken with a colored filter placed in front of the lens. Colored filters reduce transmission of specific range of colors and correspondingly affect their lightness. E.g. a Red filter darkens Blue skies. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_BLUE;Blue Channel +!TP_BWMIX_GAM_GREEN;Green Channel +!TP_BWMIX_GAM_RED;Red Channel +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each channel RGB +!TP_BWMIX_GREEN;Green +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MAGENTA;Magenta +!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 (filter, channel-mixer) to default +!TP_BWMIX_ORANGE;Orange +!TP_BWMIX_PURPLE;Purple +!TP_BWMIX_RED;Red +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all of the mixer options\nTotal displays the sum of RGB values actually applied:\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 (films, landscape, ...) or manual settings of channel-mixer +!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;Channel-Mixer absolute RGB +!TP_BWMIX_SET_RGBREL;Channel-Mixer relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Channel-Mixer absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Channel-Mixer 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_BWMIX_YELLOW;Yellow +!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) RT 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.\n 0=no effect 1=median 2=gaussian.\n\nThese artifacts are due to limitations of CIECAM02. Alternatively, adjust the image to avoid very dark shadows. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from Lab and RGB brightness +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from Lab and RGB colorfulness +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from Lab and RGB saturation +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from Lab 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 Lab and RGB contrast +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from Lab and RGB contrast +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L (Lab) 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 (Lab) 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 Lab values before CIECAM02 adjustments +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RT 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 (Lab) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in Lab 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 Lab and RGB lightness +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model\n\nWB [RT] + [output]:\nRT's white balance is used for the scene, CIECAM02 is set to D50, the output device's white balance is set in Preferences > Color Management\n\nWB [RT+CAT02] + [output]:\nRT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences +!TP_COLORAPP_RSTPRO;Red & skin tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin tones protection (sliders and curves) +!TP_COLORAPP_SHARPCIE;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe with Q/C +!TP_COLORAPP_SHARPCIE_TOOLTIP;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe will use CIECAM02 if enabled. +!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;Change tones and colors to take into account the viewing conditions of the output device\n\nAverage:\nAverage light environment (standard)\nThe image will not change\n\nDim:\nDim environment (TV)\nThe image will become slighty dark\n\nDark:\nDark environment (projector)\nThe image will become more dark\n\nExtremly Dark:\nExtremly dark environment (cutsheet)\nThe image will become very dark +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if source 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 Lab 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_CROP_GTEPASSPORT;Biometric Passport +!TP_CROP_GTFRAME;Frame +!TP_CROP_GTGRID;Grid +!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_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_CHROMA;Chrominance - Master +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on gamma of the input color profile. Gamma of sRGB is assumed, thus if input image is in color profile of a different gamma, luminance noise reduction will vary. +!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_LAB;Lab +!TP_DIRPYRDENOISE_LDETAIL;Luminance Detail +!TP_DIRPYRDENOISE_LUMA;Luminance +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or Lab methods can be used.\n\nFor non-raw images Lab method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_PERF;RGB mode (raw images) +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGB;RGB +!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_THRESHOLD;Threshold +!TP_DISTORTION_AUTO;Auto Distortion Correction +!TP_DISTORTION_AUTO_TIP;(Exprimental) Correct lens distortion automatically for some cameras (Micro 4/3, some compact digital cameras, etc.) +!TP_EPD_EDGESTOPPING;Edge Stopping +!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 via Lab mode (standard) and CIECAM02 mode.\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_EXPOSCORR_LABEL;Raw White & Black Points +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggle execution of auto levels to automatically set parameter values based on image analysis\nEnable Highlight Reconstruction if necessary +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in auto level's 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 following section of the manual to learn how to achieve the best results with double curves:\nThe Toolbox > Exposure Tab > Exposure Panel > Tone Curve +!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_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!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_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 effect of this tool or some of its sub-component is only visible at 1:1 preview scale. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Rotation anchor point X: -100=left edge, 0=center, +100=right edge +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Rotation anchor point Y: -100=top edge, 0=center, +100=bottom edge +!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 automatic exposure +!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 blown 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 simple color matrix by dcraw, enhanced RawTherapee version (whichever is available based on camera model) or embedded in 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. Use only in special cases. +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. Result can be used for calibration purposes, 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;Lab 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;Can be used with the Chromaticity slider and the CC curve. +!TP_LENSGEOM_AUTOCROP;Auto Crop +!TP_LENSGEOM_FILL;Auto fill +!TP_LENSGEOM_LABEL;Lens / Geometry +!TP_LENSPROFILE_FILEDLGFILTERLCP;Lens correction files +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;CA Correction +!TP_LENSPROFILE_USEDIST;Distortion correction +!TP_LENSPROFILE_USEVIGN;Vignetting correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset 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: 0=corners only, 50=halfway to center, 100=to center +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness: 0=rectangle, 50=fitted ellipse, 100=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. Higher = more, lower = less. +!TP_PREPROCESS_GREENEQUIL;Green Equilibration +!TP_PREPROCESS_HOTDEADPIXFILT;Hot/Dead pixel filter +!TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Try to suppress hot and dead 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_BLACKONE;Black Level: Red +!TP_RAWEXPOS_BLACKS;Black Levels +!TP_RAWEXPOS_BLACKTHREE;Black Level: Green 2 +!TP_RAWEXPOS_BLACKTWO;Black Level: Blue +!TP_RAWEXPOS_BLACKZERO;Black Level: Green 1 (lead) +!TP_RAWEXPOS_LINEAR;White Point Correction +!TP_RAWEXPOS_PRESER;Highlight Preservation +!TP_RAWEXPOS_TWOGREEN;Link greens +!TP_RAW_ALLENHANCE;Post-Demosaic Artifact/Noise Reduction +!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 +!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_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 used 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_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_ZOOMFITSCREEN;Fit 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..44b0aa9d2 --- /dev/null +++ b/rtdata/languages/default @@ -0,0 +1,1395 @@ +#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_CURVES;Curves +CURVEEDITOR_CURVE;Curve +CURVEEDITOR_CUSTOM;Custom +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_FILEDLGFILTERANY;Any files +CURVEEDITOR_FILEDLGFILTERCURVE;Curve files +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_LINEAR;Linear +CURVEEDITOR_LOADDLGLABEL;Load Curve... +CURVEEDITOR_MINMAXCPOINTS;Minima/Maxima control points +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: +EDITWINDOW_TITLE;Image Edit +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_COLORDENOISE;Bypass Color denoise +EXPORT_BYPASS_DEFRINGE;Bypass Defringe +EXPORT_BYPASS_DIRPYRDENOISE;Bypass Noise Reduction +EXPORT_BYPASS_DIRPYREQUALIZER;Bypass Contrast by Detail Levels +EXPORT_BYPASS_LUMADENOISE;Bypass Luma denoise +EXPORT_BYPASS_RAW_ALL_ENHANCE;Bypass Post Demosaic Artifact/Noise Reduction +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 +EXPORT_RESIZEMETHOD;Resize 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.\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\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_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_POPUPOPEN;Open +FILEBROWSER_POPUPPROCESSFAST;Put to Queue (Fast export) +FILEBROWSER_POPUPPROCESS;Put to Queue +FILEBROWSER_POPUPPROFILEOPERATIONS;Processing Profile Operations +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 a partial filename to search for or a comma-separated list.\nE.g. 1001,1004,1199 \n\nCtrl-F to focus to the Find text box.\nEnter to commence search.\nEsc to clear.\nShift-Esc to remove focus. +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.\nShortcut: i\n\nShortcut in Single Editor Tab Mode: Alt-i +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 images recently saved.\nShortcut: Alt-7 +FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show images not recently saved.\nShortcut: Alt-6 +FILEBROWSER_SHOWTRASHHINT;Show content of the trash.\nShortcut: T +FILEBROWSER_SHOWUNCOLORHINT;Show images without 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_USETEMPLATE;Use template: +FILEBROWSER_ZOOMINHINT;Increase thumbnail size.\nShortcut: +\n\nShortcut in Single Editor Tab Mode: Alt-+ +FILEBROWSER_ZOOMOUTHINT;Decrease thumbnail size.\nShortcut: -\n\nShortcut in Single Editor Tab Mode: Alt-- +GENERAL_ABOUT;About +GENERAL_AFTER;After +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\nClick right mouse button 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 (on) or scaled (off) 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;Lab - Lightness +HISTORY_MSG_15;Lab - Contrast +HISTORY_MSG_16;Luminance Black +HISTORY_MSG_17;Luminance Highlight Compr. +HISTORY_MSG_18;Luminance Shadow Compr. +HISTORY_MSG_19;'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 Mode 1 +HISTORY_MSG_42;Tone Curve 2 +HISTORY_MSG_43;Tone Curve Mode 2 +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;HL 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;Data specified for resize +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;Lab - Chromaticity +HISTORY_MSG_96;'a' Curve +HISTORY_MSG_97;'b' Curve +HISTORY_MSG_98;Demosaicing Method +HISTORY_MSG_99;Hot/Dead pixel filter +HISTORY_MSG_100;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;Resizing applies to +HISTORY_MSG_111;Lab - Avoid color shift +HISTORY_MSG_112;--unused-- +HISTORY_MSG_113;Lab - Protection +HISTORY_MSG_114;DCB Iterations +HISTORY_MSG_115;False Color Suppression +HISTORY_MSG_116;DCB Enhancement +HISTORY_MSG_117;Raw Red CA Correction +HISTORY_MSG_118;Raw Blue CA Correction +HISTORY_MSG_119;Line Noise Filter +HISTORY_MSG_120;Green Equilibration +HISTORY_MSG_121;Raw Auto CA +HISTORY_MSG_122;Dark Frame Auto Select +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 Select +HISTORY_MSG_128;Flat Field Blur Radius +HISTORY_MSG_129;Flat Field Blur Type +HISTORY_MSG_130;Auto Distorion +HISTORY_MSG_131;Noise Reduction Luma +HISTORY_MSG_132;Noise Reduction 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;Edges Sharpening +HISTORY_MSG_147;ES - Luminance Only +HISTORY_MSG_148;Microcontrast +HISTORY_MSG_149;Microcontrast - 3x3 matrix +HISTORY_MSG_150;Post Demosaic Artifact/Noise Reduction +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;'CC' curve +HISTORY_MSG_169;'CH' curve +HISTORY_MSG_170;Vib - Curve +HISTORY_MSG_171;'LC' curve +HISTORY_MSG_172;Lab - 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 tones protection +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 pixels +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;'CL' curve +HISTORY_MSG_247;'LH' curve +HISTORY_MSG_248;'HH' curve +HISTORY_MSG_249;CbDL - Threshold +HISTORY_MSG_250;NR - Enhanced +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 open in Editor\nShortcut: Shift-F4\n\nTo navigate to the Next image relative to thumbnail selected in File Browser\nShortcut: F4 +MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the Previous image relative to image open in Editor\nShortcut: Shift-F3 \n\nTo navigate to the Previous image relative to thumbnail selected in File Browser\nShortcut: F3 +MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronize the File Browser with the Editor to reveal the thumbnail of the currently open image, and clear filters in File Browser \nShortcut: x\n\nAs above, but without clearing filters in File Browser\nShortcut: y\n(Note that thumbnail of the open file 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 the "Preferences" dialog. +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\ndoesn't exist. Please set a correct path in the Preference window. +MAIN_MSG_QOVERWRITE;Do you want to overwrite it? +MAIN_MSG_SETPATHFIRST;You have to set a target path first in Preferences\nin order to use this function! +MAIN_MSG_WRITEFAILED;Failed to write\n\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_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_TAGGING;Tagging +MAIN_TAB_TRANSFORM;Transform +MAIN_TAB_TRANSFORM_TOOLTIP;Shortcut: Alt-t +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 10-30%\n\nPreview is rendered slower with Focus Mask turned on. +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_NA;B = n/a +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_LAB_A_NA;a = n/a +NAVIGATOR_LAB_A_VALUE;a = %1 +NAVIGATOR_LAB_B_NA;b = n/a +NAVIGATOR_LAB_B_VALUE;b = %1 +NAVIGATOR_LAB_L_NA;L = n/a +NAVIGATOR_LAB_L_VALUE;L = %1 +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_V_VALUE;V = %1 +NAVIGATOR_XY_FULL;Width = %1, Height = %2 +NAVIGATOR_XY_NA;x = n/a, y = n/a +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;90° rotation / flipping +PARTIALPASTE_COLORAPP;CIE Color Appearance Model 2002 +PARTIALPASTE_COLORGROUP;Color Related Settings +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_EVERYTHING;Everything +PARTIALPASTE_EXIFCHANGES;Changes to Exif data +PARTIALPASTE_EXPOSURE;Exposure +PARTIALPASTE_FLATFIELDAUTOSELECT;Flat field auto selection +PARTIALPASTE_FLATFIELDBLURRADIUS;Flat field blur radius +PARTIALPASTE_FLATFIELDBLURTYPE;Flat field blur type +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 info +PARTIALPASTE_LABCURVE;Lab adjustments +PARTIALPASTE_LENSGROUP;Lens Related Settings +PARTIALPASTE_LENSPROFILE;Lens correction profile +PARTIALPASTE_METAICMGROUP;Metadata/Color Management Settings +PARTIALPASTE_PCVIGNETTE;Vignette filter +PARTIALPASTE_PERSPECTIVE;Perspective +PARTIALPASTE_PREPROCESS_GREENEQUIL;Green equilibration +PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Apply hot/dead 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_ALLENHANCE;Post-demosaic artifact/noise reduction +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_WHITEBALANCE;White balance +PREFERENCES_ADD;Add +PREFERENCES_APPLNEXTSTARTUP;restart required +PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +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_BLINKCLIPPED;Blink clipped areas +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_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_CMETRICINTENT;Colorimetric intent +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 scipts 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_DATEFORMATFRAME;Date Format +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;Date format +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_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_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_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_GREY;Output device's Yb luminance (%) +PREFERENCES_GTKTHEME;GTK default +PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogram in left panel +PREFERENCES_HLTHRESHOLD;Threshold for clipped highlights +PREFERENCES_ICCDIR;Directory containing color profiles +PREFERENCES_IMPROCPARAMS;Default Image Processing Parameters +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 OS language setting +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_MONITORICC;Monitor color profile +PREFERENCES_MULTITABDUALMON;Multiple Editor Tabs Mode (if available on second monitor) +PREFERENCES_MULTITAB;Multiple Editor Tabs Mode +PREFERENCES_OUTDIRFOLDERHINT;Put the saved 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 +PREFERENCES_OVERWRITEOUTPUTFILE;Overwrite existing output files +PREFERENCES_PANFACTORFRAME;Pan Rate Amplification +PREFERENCES_PANFACTORLABEL;Factor +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;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_RGBDTL_LABEL;Max number of threads for Noise Reduction +PREFERENCES_RGBDTL_TOOLTIP;Noise Reduction requires a baseline of about 128MB RAM for a 10MPix image or 512MB for a 40MPix image, and additionally 128MB RAM per thread. The more threads run in parallel, the faster the computation. Leave the setting at "0" to automatically use as many threads as possible. +PREFERENCES_SELECTFONT;Select font +PREFERENCES_SELECTLANG;Select language +PREFERENCES_SELECTTHEME;Select theme +PREFERENCES_SET;Set +PREFERENCES_SHOWBASICEXIF;Show basic Exif info +PREFERENCES_SHOWDATETIME;Show date and time +PREFERENCES_SHOWEXPOSURECOMPENSATION;Append exposure compensation +PREFERENCES_SHOWPROFILESELECTOR;Show processing profile selector +PREFERENCES_SHTHRESHOLD;Threshold for clipped shadows +PREFERENCES_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs +PREFERENCES_SINGLETAB;Single Editor Tab Mode +PREFERENCES_SLIMUI;Slim interface +PREFERENCES_SND_BATCHQUEUEDONE;Queue processing done +PREFERENCES_SND_HELP;Either enter filepath or nothing (for no sound).\nOn Windows use "SystemDefault", "SystemAsterisk" etc. for system sounds.\nOn Linux use "complete", "window-attention" etc. for system sounds. +PREFERENCES_SND_LNGEDITPROCDONE;Editor processing done +PREFERENCES_SND_TRESHOLDSECS;after secs +PREFERENCES_SQUAREDETAILWINDOW;Square detail window (faster) +PREFERENCES_STARTUPIMDIR;Image Directory at Startup +PREFERENCES_TAB_BROWSER;File Browser +PREFERENCES_TAB_COLORMGR;Color Management +PREFERENCES_TAB_GENERAL;General +PREFERENCES_TAB_IMPROC;Image Processing +PREFERENCES_TAB_PERFORMANCE;Performance +PREFERENCES_TAB_SOUND;Sounds +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_WORKFLOW;Layout +PROFILEPANEL_COPYPPASTE;Parameters to copy +PROFILEPANEL_FILEDLGFILTERANY;Any files +PROFILEPANEL_FILEDLGFILTERPP;Processing profiles +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_JPGFILTER;JPEG files +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_TIFFFILTER;TIFF files +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_AUTOCH;Auto +TP_BWMIX_AUTOCH_TIP;Calculate values optimizing channel-mixer +TP_BWMIX_BLUE;Blue +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;Modify luminance in function of hue\nPay attention to extreme values that may cause artifacts +TP_BWMIX_CYAN;Cyan +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 simulate shots taken with a colored filter placed in front of the lens. Colored filters reduce transmission of specific range of colors and correspondingly affect their lightness. E.g. a Red filter darkens Blue skies. +TP_BWMIX_FILTER_YELLOW;Yellow +TP_BWMIX_GAMMA;Gamma Correction +TP_BWMIX_GAM_BLUE;Blue Channel +TP_BWMIX_GAM_GREEN;Green Channel +TP_BWMIX_GAM_RED;Red Channel +TP_BWMIX_GAM_TOOLTIP;Correct gamma for each channel RGB +TP_BWMIX_GREEN;Green +TP_BWMIX_LABEL;Black-and-White +TP_BWMIX_MAGENTA;Magenta +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 (filter, channel-mixer) to default +TP_BWMIX_ORANGE;Orange +TP_BWMIX_PURPLE;Purple +TP_BWMIX_RED;Red +TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all of the mixer options\nTotal displays the sum of RGB values actually applied:\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 (films, landscape, ...) or manual settings of channel-mixer +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;Channel-Mixer absolute RGB +TP_BWMIX_SET_RGBREL;Channel-Mixer relative RGB +TP_BWMIX_SET_ROYGCBPMABS;Channel-Mixer absolute ROYGCBPM +TP_BWMIX_SET_ROYGCBPMREL;Channel-Mixer 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_BWMIX_YELLOW;Yellow +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.\nShortcut: [\n\nShortcut in Single Editor Tab: Alt-[ +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotate right.\nShortcut: ]\n\nShortcut in Single Editor Tab: Alt-] +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) RT 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.\n 0=no effect 1=median 2=gaussian.\n\nThese artifacts are due to limitations of CIECAM02. Alternatively, adjust the image to avoid very dark shadows. +TP_COLORAPP_BRIGHT;Brightness (Q) +TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from Lab and RGB brightness +TP_COLORAPP_CHROMA;Chroma (C) +TP_COLORAPP_CHROMA_M;Colorfulnes (M) +TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from Lab and RGB colorfulness +TP_COLORAPP_CHROMA_S;Saturation (S) +TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from Lab and RGB saturation +TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from Lab 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 Lab and RGB contrast +TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from Lab and RGB contrast +TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L (Lab) 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 (Lab) 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 Lab values before CIECAM02 adjustments +TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RT 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 (Lab) +TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in Lab 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 Lab and RGB lightness +TP_COLORAPP_MODEL;WP Model +TP_COLORAPP_MODEL_TOOLTIP;White-Point Model\n\nWB [RT] + [output]:\nRT's white balance is used for the scene, CIECAM02 is set to D50, the output device's white balance is set in Preferences > Color Management\n\nWB [RT+CAT02] + [output]:\nRT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences +TP_COLORAPP_RSTPRO;Red & skin tones protection +TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin tones protection (sliders and curves) +TP_COLORAPP_SHARPCIE;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe with Q/C +TP_COLORAPP_SHARPCIE_TOOLTIP;Sharpening, Contrast by Detail Levels, Microcontrast & Defringe will use CIECAM02 if enabled. +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;Change tones and colors to take into account the viewing conditions of the output device\n\nAverage:\nAverage light environment (standard)\nThe image will not change\n\nDim:\nDim environment (TV)\nThe image will become slighty dark\n\nDark:\nDark environment (projector)\nThe image will become more dark\n\nExtremly Dark:\nExtremly dark environment (cutsheet)\nThe image will become very dark +TP_COLORAPP_SURSOURCE;Dark surround +TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if source 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 Lab 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_CROP_FIXRATIO;Fix ratio: +TP_CROP_GTDIAGONALS;Rule of Diagonals +TP_CROP_GTEPASSPORT;Biometric Passport +TP_CROP_GTFRAME;Frame +TP_CROP_GTGRID;Grid +TP_CROP_GTHARMMEANS1;Harmonic Means 1 +TP_CROP_GTHARMMEANS2;Harmonic Means 2 +TP_CROP_GTHARMMEANS3;Harmonic Means 3 +TP_CROP_GTHARMMEANS4;Harmonic Means 4 +TP_CROP_GTNONE;None +TP_CROP_GTRULETHIRDS;Rule of Thirds +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_BLUE;Chrominance - Blue-Yellow +TP_DIRPYRDENOISE_CHROMA;Chrominance - Master +TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on gamma of the input color profile. Gamma of sRGB is assumed, thus if input image is in color profile of a different gamma, luminance noise reduction will vary. +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_LAB;Lab +TP_DIRPYRDENOISE_LDETAIL;Luminance Detail +TP_DIRPYRDENOISE_LUMA;Luminance +TP_DIRPYRDENOISE_METHOD;Method +TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or Lab methods can be used.\n\nFor non-raw images Lab method will be used, regardless of the selection. +TP_DIRPYRDENOISE_PERF;RGB mode (raw images) +TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +TP_DIRPYRDENOISE_RGB;RGB +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_THRESHOLD;Threshold +TP_DISTORTION_AMOUNT;Amount +TP_DISTORTION_AUTO;Auto Distortion Correction +TP_DISTORTION_AUTO_TIP;(Exprimental) 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_LABEL;Tone Mapping +TP_EPD_REWEIGHTINGITERATES;Reweighting Iterates +TP_EPD_SCALE;Scale +TP_EPD_STRENGTH;Strength +TP_EPD_TOOLTIP;Tone mapping is possible via Lab mode (standard) and CIECAM02 mode.\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_EXPOSCORR_LABEL;Raw White & Black Points +TP_EXPOSURE_AUTOLEVELS;Auto Levels +TP_EXPOSURE_AUTOLEVELS_TIP;Toggle execution of auto levels to automatically set parameter values based on image analysis\nEnable 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 level's 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 following section of the manual to learn how to achieve the best results with double curves:\nThe Toolbox > Exposure Tab > Exposure Panel > Tone Curve +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_SATANDVALBLENDING;Saturation and Value Blending +TP_EXPOSURE_TCMODE_STANDARD;Standard +TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +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_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 effect of this tool or some of its sub-component is only visible at 1:1 preview scale. +TP_GRADIENT_CENTER;Center +TP_GRADIENT_CENTER_X;Center X +TP_GRADIENT_CENTER_X_TOOLTIP;Rotation anchor point X: -100=left edge, 0=center, +100=right edge +TP_GRADIENT_CENTER_Y;Center Y +TP_GRADIENT_CENTER_Y_TOOLTIP;Rotation anchor point Y: -100=top edge, 0=center, +100=bottom edge +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 automatic exposure +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 blown 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_FILEDLGFILTERANY;Any files +TP_ICM_FILEDLGFILTERICM;Color profiles +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 simple color matrix by dcraw, enhanced RawTherapee version (whichever is available based on camera model) or embedded in 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. Use 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_TOOLTIP;Save the linear TIFF image before the input profile is applied. Result can be used for calibration purposes, 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;Lab 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;Can be used with the Chromaticity slider and the CC curve. +TP_LENSGEOM_AUTOCROP;Auto Crop +TP_LENSGEOM_FILL;Auto fill +TP_LENSGEOM_LABEL;Lens / Geometry +TP_LENSPROFILE_FILEDLGFILTERLCP;Lens correction files +TP_LENSPROFILE_LABEL;Lens Correction Profile +TP_LENSPROFILE_USECA;CA Correction +TP_LENSPROFILE_USEDIST;Distortion correction +TP_LENSPROFILE_USEVIGN;Vignetting correction +TP_NEUTRAL;Neutral +TP_NEUTRAL_TIP;Reset 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: 0=corners only, 50=halfway to center, 100=to center +TP_PCVIGNETTE_LABEL;Vignette Filter +TP_PCVIGNETTE_ROUNDNESS;Roundness +TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness: 0=rectangle, 50=fitted ellipse, 100=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. Higher = more, lower = less. +TP_PREPROCESS_GREENEQUIL;Green Equilibration +TP_PREPROCESS_HOTDEADPIXFILT;Hot/Dead pixel filter +TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Try to suppress hot and dead 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_BLACKONE;Black Level: Red +TP_RAWEXPOS_BLACKS;Black Levels +TP_RAWEXPOS_BLACKTHREE;Black Level: Green 2 +TP_RAWEXPOS_BLACKTWO;Black Level: Blue +TP_RAWEXPOS_BLACKZERO;Black Level: Green 1 (lead) +TP_RAWEXPOS_LINEAR;White Point Correction +TP_RAWEXPOS_PRESER;Highlight Preservation +TP_RAWEXPOS_TWOGREEN;Link greens +TP_RAW_ALLENHANCE;Post-Demosaic Artifact/Noise Reduction +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 +TP_RAW_FALSECOLOR;False Color Suppression Steps +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_RESIZE_APPLIESTO;Applies to: +TP_RESIZE_BICUBICSF;Bicubic (Softer) +TP_RESIZE_BICUBICSH;Bicubic (Sharper) +TP_RESIZE_BICUBIC;Bicubic +TP_RESIZE_BILINEAR;Bilinear +TP_RESIZE_CROPPEDAREA;Cropped Area +TP_RESIZE_FITBOX;Bounding Box +TP_RESIZE_FULLIMAGE;Full Image +TP_RESIZE_HEIGHT;Height +TP_RESIZE_H;H: +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;W: +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;Tonal Width for Highlights +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;Tonal Width for Shadows +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 used 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_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_ZOOMFITSCREEN;Fit 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..d5806187b --- /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; +ParseExtensionsEnabled=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;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..18f7bdfed --- /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; +ParseExtensionsEnabled=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;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..4d70b9514 --- /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; +ParseExtensionsEnabled=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;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..860ef296b --- /dev/null +++ b/rtdata/profiles/BW/BW 1.pp3 @@ -0,0 +1,153 @@ +[Version] +AppVersion=4.0.12 +Version=316 + +[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.040000000000000001;0.029999999999999999;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=true +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=true +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.3999999999999999 +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 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + diff --git a/rtdata/profiles/BW/BW 2.pp3 b/rtdata/profiles/BW/BW 2.pp3 new file mode 100644 index 000000000..c2ae73014 --- /dev/null +++ b/rtdata/profiles/BW/BW 2.pp3 @@ -0,0 +1,153 @@ +[Version] +AppVersion=4.0.12 +Version=316 + +[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=true +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=true +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.3999999999999999 +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 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + diff --git a/rtdata/profiles/BW/BW 3.pp3 b/rtdata/profiles/BW/BW 3.pp3 new file mode 100644 index 000000000..d7308cb3a --- /dev/null +++ b/rtdata/profiles/BW/BW 3.pp3 @@ -0,0 +1,153 @@ +[Version] +AppVersion=4.0.12 +Version=316 + +[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=true +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=true +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.3999999999999999 +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 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + diff --git a/rtdata/profiles/BW/BW 4.pp3 b/rtdata/profiles/BW/BW 4.pp3 new file mode 100644 index 000000000..1489bfad4 --- /dev/null +++ b/rtdata/profiles/BW/BW 4.pp3 @@ -0,0 +1,153 @@ +[Version] +AppVersion=4.0.12 +Version=316 + +[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=true +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=true +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.3999999999999999 +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 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + diff --git a/rtdata/profiles/Default ISO High.pp3 b/rtdata/profiles/Default ISO High.pp3 new file mode 100644 index 000000000..e0341673a --- /dev/null +++ b/rtdata/profiles/Default ISO High.pp3 @@ -0,0 +1,179 @@ +[Version] +AppVersion=4.0.12 +Version=316 + +[Exposure] +Auto=true +Clip=0.02 +Saturation=5 +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 +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=5 +AvoidColorShift=true +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.80000000000000004 +Amount=125 +Threshold=20;80;2000;1200; +OnlyEdges=false +EdgedetectionRadius=1.8999999999999999 +EdgeTolerance=1800 +HalocontrolEnabled=false +HalocontrolAmount=85 +DeconvRadius=0.75 +DeconvAmount=75 +DeconvDamping=20 +DeconvIterations=30 + +[Vibrance] +Enabled=false +Pastels=50 +Saturated=50 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=true +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=true +Luma=50 +Ldetail=50 +Chroma=50 +Method=RGB +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.3999999999999999 +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 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[RAW] +CA=true +HotDeadPixels=true +HotDeadPixelThresh=40 +CcSteps=0 +Method=igv diff --git a/rtdata/profiles/Default ISO Medium.pp3 b/rtdata/profiles/Default ISO Medium.pp3 new file mode 100644 index 000000000..0df42baf1 --- /dev/null +++ b/rtdata/profiles/Default ISO Medium.pp3 @@ -0,0 +1,179 @@ +[Version] +AppVersion=4.0.12 +Version=316 + +[Exposure] +Auto=true +Clip=0.02 +Saturation=5 +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 +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=5 +AvoidColorShift=true +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.80000000000000004 +Amount=150 +Threshold=20;80;2000;1200; +OnlyEdges=false +EdgedetectionRadius=1.8999999999999999 +EdgeTolerance=1800 +HalocontrolEnabled=false +HalocontrolAmount=85 +DeconvRadius=0.75 +DeconvAmount=75 +DeconvDamping=20 +DeconvIterations=30 + +[Vibrance] +Enabled=false +Pastels=50 +Saturated=50 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=true +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=true +Luma=20 +Ldetail=50 +Chroma=30 +Method=RGB +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.3999999999999999 +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 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[RAW] +CA=true +HotDeadPixels=true +HotDeadPixelThresh=40 +CcSteps=0 +Method=igv diff --git a/rtdata/profiles/Default.pp3 b/rtdata/profiles/Default.pp3 new file mode 100644 index 000000000..82afac089 --- /dev/null +++ b/rtdata/profiles/Default.pp3 @@ -0,0 +1,177 @@ +[Version] +AppVersion=4.0.12 +Version=316 + +[Exposure] +Auto=true +Clip=0.02 +Saturation=10 +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 +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=0 +AvoidColorShift=true +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.8999999999999999 +EdgeTolerance=1800 +HalocontrolEnabled=false +HalocontrolAmount=85 +DeconvRadius=0.75 +DeconvAmount=75 +DeconvDamping=20 +DeconvIterations=30 + +[Vibrance] +Enabled=false +Pastels=50 +Saturated=50 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=true +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=false +Enhance=false +Luma=0 +Ldetail=50 +Chroma=15 +Method=RGB +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.3999999999999999 +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 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[RAW] +CA=true +HotDeadPixels=true +HotDeadPixelThresh=40 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..8fa7f8395 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Amber 1 TM Bright.pp3 @@ -0,0 +1,87 @@ +[Version] +AppVersion=4.0.12 +Version=315 + +[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=true +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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=50 +Chroma=20 +Method=RGB +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; + +[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; 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..364620bf0 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Amber 1 TM.pp3 @@ -0,0 +1,87 @@ +[Version] +AppVersion=4.0.12 +Version=315 + +[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=true +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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=50 +Chroma=20 +Method=RGB +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; + +[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; diff --git a/rtdata/profiles/Faded/Faded Amber 1.pp3 b/rtdata/profiles/Faded/Faded Amber 1.pp3 new file mode 100644 index 000000000..c3be435a9 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Amber 1.pp3 @@ -0,0 +1,87 @@ +[Version] +AppVersion=4.0.12 +Version=315 + +[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=true +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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=50 +Chroma=20 +Method=RGB +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; + +[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; 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..a0f58aa10 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Blue 1 TM Bright.pp3 @@ -0,0 +1,87 @@ +[Version] +AppVersion=4.0.12 +Version=315 + +[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=true +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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=50 +Chroma=20 +Method=RGB +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; + +[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; 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..f76e7aecf --- /dev/null +++ b/rtdata/profiles/Faded/Faded Blue 1 TM.pp3 @@ -0,0 +1,87 @@ +[Version] +AppVersion=4.0.12 +Version=315 + +[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=true +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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=50 +Chroma=20 +Method=RGB +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; + +[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; diff --git a/rtdata/profiles/Faded/Faded Blue 1.pp3 b/rtdata/profiles/Faded/Faded Blue 1.pp3 new file mode 100644 index 000000000..f57039519 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Blue 1.pp3 @@ -0,0 +1,87 @@ +[Version] +AppVersion=4.0.12 +Version=315 + +[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=true +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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=50 +Chroma=20 +Method=RGB +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; + +[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; 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..9fefe9ab4 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Blue Pink TM.pp3 @@ -0,0 +1,87 @@ +[Version] +AppVersion=4.0.12 +Version=315 + +[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=true +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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=50 +Chroma=20 +Method=RGB +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; + +[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; diff --git a/rtdata/profiles/Faded/Faded Blue Pink.pp3 b/rtdata/profiles/Faded/Faded Blue Pink.pp3 new file mode 100644 index 000000000..231f1ec31 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Blue Pink.pp3 @@ -0,0 +1,87 @@ +[Version] +AppVersion=4.0.12 +Version=315 + +[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=true +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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=50 +Chroma=20 +Method=RGB +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; + +[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; 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..58b29c1d6 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Chocolate 1 TM Bright.pp3 @@ -0,0 +1,91 @@ +[Version] +AppVersion=4.0.12 +Version=315 + +[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=true +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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=50 +Chroma=20 +Method=RGB +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; + +[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; 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..1d03207bc --- /dev/null +++ b/rtdata/profiles/Faded/Faded Chocolate 2 TM Bright.pp3 @@ -0,0 +1,87 @@ +[Version] +AppVersion=4.0.12 +Version=315 + +[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=true +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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=50 +Chroma=20 +Method=RGB +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; + +[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; diff --git a/rtdata/profiles/Faded/Faded Golden 1.pp3 b/rtdata/profiles/Faded/Faded Golden 1.pp3 new file mode 100644 index 000000000..73dc7cbc9 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Golden 1.pp3 @@ -0,0 +1,91 @@ +[Version] +AppVersion=4.0.12 +Version=315 + +[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=true +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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=50 +Chroma=20 +Method=RGB +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; + +[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; diff --git a/rtdata/profiles/Faded/Faded Golden 2.pp3 b/rtdata/profiles/Faded/Faded Golden 2.pp3 new file mode 100644 index 000000000..5f76b4aec --- /dev/null +++ b/rtdata/profiles/Faded/Faded Golden 2.pp3 @@ -0,0 +1,91 @@ +[Version] +AppVersion=4.0.12 +Version=315 + +[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=true +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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=50 +Chroma=20 +Method=RGB +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; + +[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; 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..fad2ce408 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Green 1 TM Bright.pp3 @@ -0,0 +1,87 @@ +[Version] +AppVersion=4.0.12 +Version=315 + +[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=true +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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=50 +Chroma=20 +Method=RGB +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; + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; 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..74e4656ec --- /dev/null +++ b/rtdata/profiles/Faded/Faded Green 1 TM.pp3 @@ -0,0 +1,87 @@ +[Version] +AppVersion=4.0.12 +Version=315 + +[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=true +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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=50 +Chroma=20 +Method=RGB +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; + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; diff --git a/rtdata/profiles/Faded/Faded Green 1.pp3 b/rtdata/profiles/Faded/Faded Green 1.pp3 new file mode 100644 index 000000000..2f0e7386d --- /dev/null +++ b/rtdata/profiles/Faded/Faded Green 1.pp3 @@ -0,0 +1,91 @@ +[Version] +AppVersion=4.0.12 +Version=315 + +[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=true +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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=50 +Chroma=20 +Method=RGB +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; + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; diff --git a/rtdata/profiles/Faded/Faded Green 2.pp3 b/rtdata/profiles/Faded/Faded Green 2.pp3 new file mode 100644 index 000000000..4a377328c --- /dev/null +++ b/rtdata/profiles/Faded/Faded Green 2.pp3 @@ -0,0 +1,91 @@ +[Version] +AppVersion=4.0.12 +Version=315 + +[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=true +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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=50 +Chroma=20 +Method=RGB +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; + +[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; diff --git a/rtdata/profiles/Faded/Faded Green 3.pp3 b/rtdata/profiles/Faded/Faded Green 3.pp3 new file mode 100644 index 000000000..9b7babee4 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Green 3.pp3 @@ -0,0 +1,87 @@ +[Version] +AppVersion=4.0.12 +Version=315 + +[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=true +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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=50 +Chroma=20 +Method=RGB +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; + +[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; diff --git a/rtdata/profiles/Faded/Faded Neutral TM.pp3 b/rtdata/profiles/Faded/Faded Neutral TM.pp3 new file mode 100644 index 000000000..64d99890b --- /dev/null +++ b/rtdata/profiles/Faded/Faded Neutral TM.pp3 @@ -0,0 +1,87 @@ +[Version] +AppVersion=4.0.12 +Version=315 + +[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=true +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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=50 +Chroma=20 +Method=RGB +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; + +[RGB Curves] +LumaMode=false +rCurve=3;0;0;1;1; +gCurve=3;0;0;1;1; +bCurve=3;0;0;1;1; diff --git a/rtdata/profiles/Faded/Faded Neutral.pp3 b/rtdata/profiles/Faded/Faded Neutral.pp3 new file mode 100644 index 000000000..3dae8d760 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Neutral.pp3 @@ -0,0 +1,87 @@ +[Version] +AppVersion=4.0.12 +Version=315 + +[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=true +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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=50 +Chroma=20 +Method=RGB +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; + +[RGB Curves] +LumaMode=false +rCurve=3;0;0;1;1; +gCurve=3;0;0;1;1; +bCurve=3;0;0;1;1; 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..53b69871a --- /dev/null +++ b/rtdata/profiles/Faded/Faded Purple 1 TM Bright.pp3 @@ -0,0 +1,87 @@ +[Version] +AppVersion=4.0.12 +Version=315 + +[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=true +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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=50 +Chroma=20 +Method=RGB +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; + +[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; 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..3ecb0c6a5 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Purple 1 TM.pp3 @@ -0,0 +1,91 @@ +[Version] +AppVersion=4.0.12 +Version=315 + +[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=true +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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=50 +Chroma=20 +Method=RGB +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; + +[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; diff --git a/rtdata/profiles/Faded/Faded Purple 1.pp3 b/rtdata/profiles/Faded/Faded Purple 1.pp3 new file mode 100644 index 000000000..21be1473d --- /dev/null +++ b/rtdata/profiles/Faded/Faded Purple 1.pp3 @@ -0,0 +1,91 @@ +[Version] +AppVersion=4.0.12 +Version=315 + +[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=true +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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=50 +Chroma=20 +Method=RGB +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; + +[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; 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..767534268 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Purple 2 TM.pp3 @@ -0,0 +1,91 @@ +[Version] +AppVersion=4.0.12 +Version=315 + +[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=true +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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=50 +Chroma=20 +Method=RGB +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; + +[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; diff --git a/rtdata/profiles/Faded/Faded Purple 2.pp3 b/rtdata/profiles/Faded/Faded Purple 2.pp3 new file mode 100644 index 000000000..5411da102 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Purple 2.pp3 @@ -0,0 +1,91 @@ +[Version] +AppVersion=4.0.12 +Version=315 + +[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=true +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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=50 +Chroma=20 +Method=RGB +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; + +[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; 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..a623115d0 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Teal Orange TM Bright.pp3 @@ -0,0 +1,87 @@ +[Version] +AppVersion=4.0.12 +Version=315 + +[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=true +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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=50 +Chroma=20 +Method=RGB +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.34999999999999998;0.34999999999999998;0.33333333333333331;0.5;0.34999999999999998;0.34999999999999998;0.5;0.5;0.34999999999999998;0.34999999999999998;0.66666666666666663;0.5;0.34999999999999998;0.34999999999999998;0.83333333333333326;0.5;0.34999999999999998;0.34999999999999998; +VCurve=0; + +[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; 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..663810358 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Teal Orange TM.pp3 @@ -0,0 +1,87 @@ +[Version] +AppVersion=4.0.12 +Version=315 + +[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=true +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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=50 +Chroma=20 +Method=RGB +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.34999999999999998;0.34999999999999998;0.33333333333333331;0.5;0.34999999999999998;0.34999999999999998;0.5;0.5;0.34999999999999998;0.34999999999999998;0.66666666666666663;0.5;0.34999999999999998;0.34999999999999998;0.83333333333333326;0.5;0.34999999999999998;0.34999999999999998; +VCurve=0; + +[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; diff --git a/rtdata/profiles/Faded/Faded Teal Orange.pp3 b/rtdata/profiles/Faded/Faded Teal Orange.pp3 new file mode 100644 index 000000000..fec0b7a61 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Teal Orange.pp3 @@ -0,0 +1,87 @@ +[Version] +AppVersion=4.0.12 +Version=315 + +[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=true +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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=50 +Chroma=20 +Method=RGB +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.34999999999999998;0.34999999999999998;0.33333333333333331;0.5;0.34999999999999998;0.34999999999999998;0.5;0.5;0.34999999999999998;0.34999999999999998;0.66666666666666663;0.5;0.34999999999999998;0.34999999999999998;0.83333333333333326;0.5;0.34999999999999998;0.34999999999999998; +VCurve=0; + +[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; 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..f3ac4cbc8 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Warm 1 TM Bright.pp3 @@ -0,0 +1,91 @@ +[Version] +AppVersion=4.0.12 +Version=315 + +[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=true +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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=50 +Chroma=20 +Method=RGB +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; + +[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; 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..7553be623 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Warm 1 TM.pp3 @@ -0,0 +1,91 @@ +[Version] +AppVersion=4.0.12 +Version=315 + +[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=true +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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=50 +Chroma=20 +Method=RGB +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; + +[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; diff --git a/rtdata/profiles/Faded/Faded Warm 1.pp3 b/rtdata/profiles/Faded/Faded Warm 1.pp3 new file mode 100644 index 000000000..5043341ef --- /dev/null +++ b/rtdata/profiles/Faded/Faded Warm 1.pp3 @@ -0,0 +1,91 @@ +[Version] +AppVersion=4.0.12 +Version=315 + +[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=true +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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=50 +Chroma=20 +Method=RGB +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; + +[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; diff --git a/rtdata/profiles/Faded/Faded Warm 2.pp3 b/rtdata/profiles/Faded/Faded Warm 2.pp3 new file mode 100644 index 000000000..092e24444 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Warm 2.pp3 @@ -0,0 +1,87 @@ +[Version] +AppVersion=4.0.12 +Version=315 + +[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=true +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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=50 +Chroma=20 +Method=RGB +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; + +[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; diff --git a/rtdata/profiles/Faded/Faded Warm 3.pp3 b/rtdata/profiles/Faded/Faded Warm 3.pp3 new file mode 100644 index 000000000..934d37026 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Warm 3.pp3 @@ -0,0 +1,87 @@ +[Version] +AppVersion=4.0.12 +Version=315 + +[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=true +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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=50 +Chroma=20 +Method=RGB +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; + +[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; diff --git a/rtdata/profiles/Generic/Deep Shadows.pp3 b/rtdata/profiles/Generic/Deep Shadows.pp3 new file mode 100644 index 000000000..a8df52a76 --- /dev/null +++ b/rtdata/profiles/Generic/Deep Shadows.pp3 @@ -0,0 +1,153 @@ +[Version] +AppVersion=4.0.12 +Version=316 + +[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=true +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=true +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.3999999999999999 +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 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + diff --git a/rtdata/profiles/Generic/Equilibrated.pp3 b/rtdata/profiles/Generic/Equilibrated.pp3 new file mode 100644 index 000000000..f929dd841 --- /dev/null +++ b/rtdata/profiles/Generic/Equilibrated.pp3 @@ -0,0 +1,153 @@ +[Version] +AppVersion=4.0.12 +Version=316 + +[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=true +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=true +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.3999999999999999 +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 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + diff --git a/rtdata/profiles/Generic/High-Key.pp3 b/rtdata/profiles/Generic/High-Key.pp3 new file mode 100644 index 000000000..8560a9a21 --- /dev/null +++ b/rtdata/profiles/Generic/High-Key.pp3 @@ -0,0 +1,153 @@ +[Version] +AppVersion=4.0.12 +Version=316 + +[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=true +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=true +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.3999999999999999 +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 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + diff --git a/rtdata/profiles/Generic/Natural 1.pp3 b/rtdata/profiles/Generic/Natural 1.pp3 new file mode 100644 index 000000000..c9adbf403 --- /dev/null +++ b/rtdata/profiles/Generic/Natural 1.pp3 @@ -0,0 +1,153 @@ +[Version] +AppVersion=4.0.12 +Version=316 + +[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.040000000000000001;0.029999999999999999;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=true +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=true +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.3999999999999999 +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 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + diff --git a/rtdata/profiles/Generic/Natural 2.pp3 b/rtdata/profiles/Generic/Natural 2.pp3 new file mode 100644 index 000000000..bd1a3ee47 --- /dev/null +++ b/rtdata/profiles/Generic/Natural 2.pp3 @@ -0,0 +1,153 @@ +[Version] +AppVersion=4.0.12 +Version=316 + +[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=true +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=true +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.3999999999999999 +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 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + diff --git a/rtdata/profiles/Generic/Punchy 1.pp3 b/rtdata/profiles/Generic/Punchy 1.pp3 new file mode 100644 index 000000000..a2c8dc2de --- /dev/null +++ b/rtdata/profiles/Generic/Punchy 1.pp3 @@ -0,0 +1,153 @@ +[Version] +AppVersion=4.0.12 +Version=316 + +[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=true +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=true +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.3999999999999999 +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 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + diff --git a/rtdata/profiles/Generic/Punchy 2.pp3 b/rtdata/profiles/Generic/Punchy 2.pp3 new file mode 100644 index 000000000..825eddec2 --- /dev/null +++ b/rtdata/profiles/Generic/Punchy 2.pp3 @@ -0,0 +1,153 @@ +[Version] +AppVersion=4.0.12 +Version=316 + +[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=true +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=true +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.3999999999999999 +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 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + diff --git a/rtdata/profiles/Pop/Pop 1.pp3 b/rtdata/profiles/Pop/Pop 1.pp3 new file mode 100644 index 000000000..75532b35e --- /dev/null +++ b/rtdata/profiles/Pop/Pop 1.pp3 @@ -0,0 +1,154 @@ +[Version] +AppVersion=4.0.12 +Version=316 + +[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.084000000000000005;0;0.187;0.188;0.442;0.57599999999999996;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 +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=0 +AvoidColorShift=true +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=3;0;0;0.5;0.40000000000000002;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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=true +Degree=98 +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.14999999999999999;0;0.67000000000000004;0.91000000000000003;1;1; +Curve3=3;0;0;0.080000000000000002;0.02;0.29999999999999999;0.5;1;1; + +[EPD] +Enabled=true +Strength=0.25 +EdgeStopping=2.3999999999999999 +Scale=0.10000000000000001 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=20 +HighlightTonalWidth=80 +Shadows=20 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=70 + +[Gradient] +Enabled=false +Degree=0 +Feather=25 +Strength=0 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=true +Strength=1 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false + +[RAW] +CA=true +HotDeadPixels=true +HotDeadPixelThresh=40 \ No newline at end of file diff --git a/rtdata/profiles/Pop/Pop 2 L.pp3 b/rtdata/profiles/Pop/Pop 2 L.pp3 new file mode 100644 index 000000000..86ffd4931 --- /dev/null +++ b/rtdata/profiles/Pop/Pop 2 L.pp3 @@ -0,0 +1,154 @@ +[Version] +AppVersion=4.0.12 +Version=316 + +[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.17899999999999999;0;0.38400000000000001;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 +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=0 +AvoidColorShift=true +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=3;0;0;0.12;0.29999999999999999;0.5;0.46000000000000002;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=true +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=6050 +AutoAdapscen=true +SurrSource=false +Gamut=true +Datacie=false +Tonecie=true +CurveMode=Brightness +CurveMode2=Lightness +CurveMode3=Colorfullness +Curve=0; +Curve2=3;0;0;0.14999999999999999;0;0.67000000000000004;0.91000000000000003;1;1; +Curve3=3;0;0;0.080000000000000002;0.02;0.29999999999999999;0.5;1;1; + +[EPD] +Enabled=true +Strength=0.25 +EdgeStopping=2.3999999999999999 +Scale=0.10000000000000001 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=20 +HighlightTonalWidth=80 +Shadows=20 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=70 + +[Gradient] +Enabled=false +Degree=0 +Feather=25 +Strength=0 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=true +Strength=1 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false + +[RAW] +CA=true +HotDeadPixels=true +HotDeadPixelThresh=40 \ No newline at end of file diff --git a/rtdata/profiles/Pop/Pop 3 Skin.pp3 b/rtdata/profiles/Pop/Pop 3 Skin.pp3 new file mode 100644 index 000000000..72ddb5d47 --- /dev/null +++ b/rtdata/profiles/Pop/Pop 3 Skin.pp3 @@ -0,0 +1,154 @@ +[Version] +AppVersion=4.0.12 +Version=316 + +[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.084000000000000005;0;0.187;0.188;0.442;0.57599999999999996;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 +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=0 +AvoidColorShift=true +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=3;0;0;0.5;0.40000000000000002;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=true +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=20 +H-Hue=0 +RSTProtection=55 +AdaptScene=6050 +AutoAdapscen=true +SurrSource=false +Gamut=true +Datacie=false +Tonecie=true +CurveMode=Brightness +CurveMode2=Lightness +CurveMode3=Colorfullness +Curve=0; +Curve2=3;0;0;0.14999999999999999;0;0.67000000000000004;0.91000000000000003;1;1; +Curve3=3;0;0;0.080000000000000002;0.02;0.38;0.72999999999999998;1;1; + +[EPD] +Enabled=true +Strength=0.25 +EdgeStopping=2.3999999999999999 +Scale=0.10000000000000001 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=20 +HighlightTonalWidth=80 +Shadows=20 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=70 + +[Gradient] +Enabled=false +Degree=0 +Feather=25 +Strength=0 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=true +Strength=1 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false + +[RAW] +CA=true +HotDeadPixels=true +HotDeadPixelThresh=40 \ No newline at end of file diff --git a/rtdata/profiles/Pop/Pop 4 BW.pp3 b/rtdata/profiles/Pop/Pop 4 BW.pp3 new file mode 100644 index 000000000..aec0220a8 --- /dev/null +++ b/rtdata/profiles/Pop/Pop 4 BW.pp3 @@ -0,0 +1,154 @@ +[Version] +AppVersion=4.0.12 +Version=316 + +[Exposure] +Auto=false +Clip=0.02 +Compensation=0.66000000000000003 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=Standard +Curve=3;0;0;0.084000000000000005;0;0.187;0.188;0.58699999999999997;0.74199999999999999;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=false +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 +LuminanceCurve=0; +BeforeCurveMode=Standard +AfterCurveMode=Standard +BeforeCurve=0; +AfterCurve=0; + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=0 +AvoidColorShift=true +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=3;0;0;0.21199999999999999;0.11899999999999999;0.67400000000000004;0.77300000000000002;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=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=true +Degree=97 +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=164.32900000000001 +AutoAdapscen=true +SurrSource=false +Gamut=true +Datacie=false +Tonecie=true +CurveMode=Lightness +CurveMode2=Lightness +CurveMode3=Colorfullness +Curve=3;0;0;0.14999999999999999;0;0.54500000000000004;1;1;1; +Curve2=0; +Curve3=0; + +[EPD] +Enabled=true +Strength=0.25 +EdgeStopping=2.3999999999999999 +Scale=0.10000000000000001 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=20 +HighlightTonalWidth=80 +Shadows=20 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=70 + +[Gradient] +Enabled=false +Degree=0 +Feather=25 +Strength=0 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=true +Strength=1 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false + +[RAW] +CA=true +HotDeadPixels=true +HotDeadPixelThresh=40 \ No newline at end of file diff --git a/rtdata/profiles/Portrait/Portrait Lejto.pp3 b/rtdata/profiles/Portrait/Portrait Lejto.pp3 new file mode 100644 index 000000000..c49b6eff2 --- /dev/null +++ b/rtdata/profiles/Portrait/Portrait Lejto.pp3 @@ -0,0 +1,153 @@ +[Version] +AppVersion=4.0.12 +Version=316 + +[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.029999999999999999;0.18041642857142856;0.21375157142857143;0.70232600000000001;0.74883699999999997;1;1; +Curve2=1;0;0;0.075000000000000691;0.13571428571428609;0.29999999999999999;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=true +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=true +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.3999999999999999 +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 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + diff --git a/rtdata/profiles/Portrait/Portrait Smooth.pp3 b/rtdata/profiles/Portrait/Portrait Smooth.pp3 new file mode 100644 index 000000000..a70e7ce4d --- /dev/null +++ b/rtdata/profiles/Portrait/Portrait Smooth.pp3 @@ -0,0 +1,153 @@ +[Version] +AppVersion=4.0.12 +Version=316 + +[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.57399999999999995;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 +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=-20 +Contrast=-20 +Chromaticity=0 +AvoidColorShift=true +RedAndSkinTonesProtection=50 +LCredsk=true +LCurve=3;0;0;0.042700000000000002;0.014;0.16200000000000001;0.16200000000000001;0.54700000000000004;0.93300000000000005;1;1; +aCurve=0; +bCurve=0; +ccCurve=1;0;0;0.254;0.29999999999999999;1;1; +chCurve=0; +lhCurve=0; +hhCurve=0; +LcCurve=0; +ClCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=75;75; +ProtectSkins=false +AvoidColorShift=true +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false +Degree=100 +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.29999999999999999 +EdgeStopping=1.3999999999999999 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=10 +HighlightTonalWidth=80 +Shadows=10 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=70 + +[Gradient] +Enabled=false +Degree=0 +Feather=25 +Strength=0 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=1;0;0.5;0.34999999999999998;0.34999999999999998;0.16400000000000001;0.48999999999999999;0.34999999999999998;0.34999999999999998;0.33300000000000002;0.5;0.34999999999999998;0.34999999999999998;0.5;0.5;0.34999999999999998;0.34999999999999998;0.66600000000000004;0.5;0.34999999999999998;0.34999999999999998;0.83299999999999996;0.5;0.34999999999999998;0.34999999999999998; +SCurve=0; +VCurve=1;0;0.5;0.34999999999999998;0.34999999999999998;0.16600000000000001;0.5;0.34999999999999998;0.34999999999999998;0.33300000000000002;0.5;0.34999999999999998;0.34999999999999998;0.5;0.5;0.34999999999999998;0.34999999999999998;0.66600000000000004;0.5;0.34999999999999998;0.34999999999999998;0.83299999999999996;0.5;0.34999999999999998;0.34999999999999998; + +[RGB Curves] +LumaMode=false +rCurve=1;0;0;0.25;0.25;0.5;0.5;0.75;0.75;1;1; +gCurve=1;0;0;0.25;0.25;0.5;0.5;0.75;0.75;1;1; +bCurve=1;0;0;0.25;0.25;0.5;0.5;0.75;0.75;1;1; + diff --git a/rtdata/profiles/Skintones/Skintones - Natural TM.pp3 b/rtdata/profiles/Skintones/Skintones - Natural TM.pp3 new file mode 100644 index 000000000..4358d91f6 --- /dev/null +++ b/rtdata/profiles/Skintones/Skintones - Natural TM.pp3 @@ -0,0 +1,163 @@ +[Version] +AppVersion=4.0.12 +Version=316 + +[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=true +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=true +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=50 +Chroma=15 +Method=RGB +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=true +Strength=0.25 +EdgeStopping=1.3999999999999999 +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 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; diff --git a/rtdata/profiles/Skintones/Skintones - Natural.pp3 b/rtdata/profiles/Skintones/Skintones - Natural.pp3 new file mode 100644 index 000000000..a202b41a6 --- /dev/null +++ b/rtdata/profiles/Skintones/Skintones - Natural.pp3 @@ -0,0 +1,163 @@ +[Version] +AppVersion=4.0.12 +Version=316 + +[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=true +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=true +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=50 +Chroma=15 +Method=RGB +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.3999999999999999 +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 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; 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..b61f34115 --- /dev/null +++ b/rtdata/profiles/Skintones/Skintones - Pale TM Bright.pp3 @@ -0,0 +1,163 @@ +[Version] +AppVersion=4.0.12 +Version=316 + +[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=true +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=true +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=50 +Chroma=15 +Method=RGB +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=true +Strength=0.25 +EdgeStopping=1.3999999999999999 +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 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; diff --git a/rtdata/profiles/Skintones/Skintones - Pale TM.pp3 b/rtdata/profiles/Skintones/Skintones - Pale TM.pp3 new file mode 100644 index 000000000..0afc0aae3 --- /dev/null +++ b/rtdata/profiles/Skintones/Skintones - Pale TM.pp3 @@ -0,0 +1,163 @@ +[Version] +AppVersion=4.0.12 +Version=316 + +[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=true +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=true +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=50 +Chroma=15 +Method=RGB +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=true +Strength=0.25 +EdgeStopping=1.3999999999999999 +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 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; diff --git a/rtdata/profiles/Skintones/Skintones - Pale.pp3 b/rtdata/profiles/Skintones/Skintones - Pale.pp3 new file mode 100644 index 000000000..c700bd4ba --- /dev/null +++ b/rtdata/profiles/Skintones/Skintones - Pale.pp3 @@ -0,0 +1,163 @@ +[Version] +AppVersion=4.0.12 +Version=316 + +[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=true +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=50 +Chroma=15 +Method=RGB +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.3999999999999999 +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 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; diff --git a/rtdata/profiles/Skintones/Skintones - Soft Texture.pp3 b/rtdata/profiles/Skintones/Skintones - Soft Texture.pp3 new file mode 100644 index 000000000..c7df0a49e --- /dev/null +++ b/rtdata/profiles/Skintones/Skintones - Soft Texture.pp3 @@ -0,0 +1,163 @@ +[Version] +AppVersion=4.0.12 +Version=316 + +[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=true +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=true +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=50 +Chroma=15 +Method=RGB +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.3999999999999999 +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 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[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; diff --git a/rtdata/profiles/Skintones/Skintones - Strong Texture.pp3 b/rtdata/profiles/Skintones/Skintones - Strong Texture.pp3 new file mode 100644 index 000000000..1b9392e77 --- /dev/null +++ b/rtdata/profiles/Skintones/Skintones - Strong Texture.pp3 @@ -0,0 +1,163 @@ +[Version] +AppVersion=4.0.12 +Version=316 + +[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=true +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=true +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=50 +Chroma=15 +Method=RGB +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.3999999999999999 +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 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[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; diff --git a/rtdata/profiles/Skintones/Skintones - Studio TM.pp3 b/rtdata/profiles/Skintones/Skintones - Studio TM.pp3 new file mode 100644 index 000000000..fff6021d3 --- /dev/null +++ b/rtdata/profiles/Skintones/Skintones - Studio TM.pp3 @@ -0,0 +1,163 @@ +[Version] +AppVersion=4.0.12 +Version=316 + +[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=true +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=true +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=50 +Chroma=15 +Method=RGB +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=true +Strength=0.14999999999999999 +EdgeStopping=1.3999999999999999 +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 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; diff --git a/rtdata/profiles/Skintones/Skintones - Studio.pp3 b/rtdata/profiles/Skintones/Skintones - Studio.pp3 new file mode 100644 index 000000000..b06905a8d --- /dev/null +++ b/rtdata/profiles/Skintones/Skintones - Studio.pp3 @@ -0,0 +1,163 @@ +[Version] +AppVersion=4.0.12 +Version=316 + +[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=true +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=true +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=50 +Chroma=15 +Method=RGB +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.14999999999999999 +EdgeStopping=1.3999999999999999 +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 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; 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..66d19c565 --- /dev/null +++ b/rtdata/profiles/Skintones/Skintones - StudioBase 1 TM.pp3 @@ -0,0 +1,163 @@ +[Version] +AppVersion=4.0.12 +Version=316 + +[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=true +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=true +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=50 +Chroma=15 +Method=RGB +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=true +Strength=0.14999999999999999 +EdgeStopping=1.3999999999999999 +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 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; diff --git a/rtdata/profiles/Skintones/Skintones - StudioBase 1.pp3 b/rtdata/profiles/Skintones/Skintones - StudioBase 1.pp3 new file mode 100644 index 000000000..2ec4a8ff3 --- /dev/null +++ b/rtdata/profiles/Skintones/Skintones - StudioBase 1.pp3 @@ -0,0 +1,163 @@ +[Version] +AppVersion=4.0.12 +Version=316 + +[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=true +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=true +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=50 +Chroma=15 +Method=RGB +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.14999999999999999 +EdgeStopping=1.3999999999999999 +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 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; 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..a5f0626e6 --- /dev/null +++ b/rtdata/themes/09-Gray-Orange.gtkrc @@ -0,0 +1,488 @@ +# +# 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:#0A0A0A\nrt_fg_color:#757575\nrt_tooltip_fg_color:#D2D2D2\nrt_selected_bg_color:#B3641B\nrt_selected_fg_color:#D0D0D0\nrt_text_color:#757575\nrt_bg_color:#181818\nrt_tooltip_bg_color:#5A5A5A" + +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 = 18 + GtkExpander::expander-spacing = 0 + 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-framelessspinbutton" { + + # IMPORTANT! + # base[NORMAL] must have the same color than notebook bg[NORMAL] + base[NORMAL] = shade (1.02, @rt_bg_color) +} + +style "clearlooks-scale" { + xthickness = 2 + ythickness = 2 + + bg[NORMAL] = shade (1.80, @rt_bg_color) + bg[PRELIGHT] = shade (2.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" { + + bg[ACTIVE] = shade (2.25, @rt_bg_color) + bg[PRELIGHT] = shade (3.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" { + + # IMPORTANT! + # If you modify bg[NORMAL] here under, you must set clearlooks-framelessspinbutton -> base[NORMAL] to the very same value + bg[NORMAL] = shade (1.02, @rt_bg_color) + bg[ACTIVE] = @rt_base_color +} + +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 (1.45, @rt_bg_color) + bg[PRELIGHT] = shade (1.65, @rt_bg_color) + bg[ACTIVE] = shade (2.00, @rt_bg_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" { + + fg[NORMAL] = @rt_salt_pinch + fg[PRELIGHT] = @rt_salt_pinch + fg[INSENSITIVE] = @rt_salt_pinch + + 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 + + engine "clearlooks" { + hint = "expander" + } +} + +style "clearlooks-expanderLabel" { + + fg[NORMAL] = shade (1.50, @rt_text_color) + fg[PRELIGHT] = @rt_selected_fg_color +} + +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-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 "GtkExpander" style "clearlooks-expander" +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-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-expanderLabel" +widget_class "*.." style "clearlooks-expanderLabel" + +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_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 "*.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" + +# 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..d504a38d9 --- /dev/null +++ b/rtdata/themes/17-Gray-Red.gtkrc @@ -0,0 +1,488 @@ +# +# 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" + +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 = 18 + GtkExpander::expander-spacing = 0 + 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-framelessspinbutton" { + + # IMPORTANT! + # base[NORMAL] must have the same color than notebook bg[NORMAL] + base[NORMAL] = shade (1.02, @rt_bg_color) +} + +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" { + + bg[ACTIVE] = shade (1.35, @rt_bg_color) + bg[PRELIGHT] = shade (1.70, @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" { + + # IMPORTANT! + # If you modify bg[NORMAL] here under, you must set clearlooks-framelessspinbutton -> base[NORMAL] to the very same value + bg[NORMAL] = shade (1.02, @rt_bg_color) + bg[ACTIVE] = shade (0.80, @rt_bg_color) +} + +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 (1.25, @rt_bg_color) + bg[PRELIGHT] = shade (1.50, @rt_bg_color) + bg[ACTIVE] = shade (1.70, @rt_bg_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" { + + fg[NORMAL] = @rt_salt_pinch + fg[PRELIGHT] = @rt_salt_pinch + fg[INSENSITIVE] = @rt_salt_pinch + + 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 + + engine "clearlooks" { + hint = "expander" + } +} + +style "clearlooks-expanderLabel" { + + fg[NORMAL] = "#a0a0a0" + fg[PRELIGHT] = "#d0d0d0" +} + +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-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 "GtkExpander" style "clearlooks-expander" +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-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-expanderLabel" +widget_class "*.." style "clearlooks-expanderLabel" + +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_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 "*.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" + +# 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..03feec79d --- /dev/null +++ b/rtdata/themes/21-Gray-Gray.gtkrc @@ -0,0 +1,500 @@ +# +# 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:#B0B0B0\nrt_tooltip_fg_color:#1A1A1A\nrt_selected_bg_color:#4A4A4A\nrt_selected_fg_color:#B0B0B0\nrt_text_color:#909090\nrt_bg_color:#363636\nrt_tooltip_bg_color:#909090" + +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 = 14 + GtkExpander::expander-spacing = 3 + 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-framelessspinbutton" { + + # IMPORTANT! + # base[NORMAL] must have the same color than notebook bg[NORMAL] + base[NORMAL] = shade (1.02, @rt_bg_color) +} + +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" { + + 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" { + + # IMPORTANT! + # If you modify bg[NORMAL] here under, you must set clearlooks-framelessspinbutton -> base[NORMAL] to the very same value + bg[NORMAL] = shade (1.02, @rt_bg_color) + bg[ACTIVE] = @rt_base_color +} + +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 (1.35, @rt_bg_color) + bg[PRELIGHT] = shade (1.55, @rt_bg_color) + bg[ACTIVE] = shade (1.80, @rt_bg_color) + + engine "clearlooks" + { + hint = "button" + } +} + +style "clearlooks-checkbutton" { + + bg[SELECTED] = darker (@rt_fg_color) + + engine "clearlooks" + { + hint = "checkbutton" + } +} + +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" { + + fg[NORMAL] = @rt_salt_pinch + fg[PRELIGHT] = @rt_salt_pinch + fg[INSENSITIVE] = @rt_salt_pinch + + 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 + + engine "clearlooks" { + hint = "expander" + } +} + +style "clearlooks-expanderLabel" { + + fg[NORMAL] = shade (1.50, @rt_text_color) + fg[PRELIGHT] = shade (1.50, @rt_text_color) +} + +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.20, @rt_fg_color, @rt_bg_color) +} + +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 "GtkExpander" style "clearlooks-expander" +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-button" +widget_class "*" style "clearlooks-checkbutton" +widget_class "*" style "clearlooks-notebook" +widget_class "**" style "clearlooks-statusbar" + +#widget_class "**" style "clearlooks-comboboxentry" +widget_class "**" style "clearlooks-combobox" + +widget_class "*." style "clearlooks-expanderLabel" +widget_class "*.." style "clearlooks-expanderLabel" + +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_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 "*.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" + +# 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/25-Gray-Gray.gtkrc b/rtdata/themes/25-Gray-Gray.gtkrc new file mode 100644 index 000000000..3d262d856 --- /dev/null +++ b/rtdata/themes/25-Gray-Gray.gtkrc @@ -0,0 +1,486 @@ +# +# 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:#484848\nrt_fg_color:#8c8c8c\nrt_tooltip_fg_color:#D2D2D2\nrt_selected_bg_color:#606060\nrt_selected_fg_color:#C0C0C0\nrt_text_color:#8c8c8c\nrt_bg_color:#404040\nrt_tooltip_bg_color:#5A5A5A" + +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 = 18 + GtkExpander::expander-spacing = 0 + 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_selected_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_selected_fg_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-framelessspinbutton" { + + # IMPORTANT! + # base[NORMAL] must have the same color than notebook bg[NORMAL] + base[NORMAL] = shade (1.02, @rt_bg_color) +} + +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" { + + bg[ACTIVE] = shade (1.40, @rt_bg_color) + bg[PRELIGHT] = shade (1.70, @rt_bg_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" { + + # IMPORTANT! + # If you modify bg[NORMAL] here under, you must set clearlooks-framelessspinbutton -> base[NORMAL] to the very same value + bg[NORMAL] = shade (1.02, @rt_bg_color) + bg[ACTIVE] = shade (0.80, @rt_bg_color) +} + +style "clearlooks-combobox" { + + text[NORMAL] = @rt_fg_color + text[PRELIGHT] = @rt_selected_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.25, @rt_bg_color) + bg[PRELIGHT] = shade (1.50, @rt_bg_color) + bg[ACTIVE] = shade (1.70, @rt_bg_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" { + + fg[NORMAL] = @rt_salt_pinch + fg[PRELIGHT] = @rt_salt_pinch + fg[INSENSITIVE] = @rt_salt_pinch + + 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 + + engine "clearlooks" { + hint = "expander" + } +} + +style "clearlooks-expanderLabel" { + + fg[NORMAL] = "#a0a0a0" + fg[PRELIGHT] = "#d0d0d0" +} + +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-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 "GtkExpander" style "clearlooks-expander" +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-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-expanderLabel" +widget_class "*.." style "clearlooks-expanderLabel" + +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_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 "*.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" + +# 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..f2973fbd9 --- /dev/null +++ b/rtdata/themes/25-Gray-Purple.gtkrc @@ -0,0 +1,486 @@ +# +# 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" + +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 = 18 + GtkExpander::expander-spacing = 0 + 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-framelessspinbutton" { + + # IMPORTANT! + # base[NORMAL] must have the same color than notebook bg[NORMAL] + base[NORMAL] = shade (1.02, @rt_bg_color) +} + +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" { + + bg[ACTIVE] = shade (1.40, @rt_bg_color) + bg[PRELIGHT] = shade (1.70, @rt_bg_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" { + + # IMPORTANT! + # If you modify bg[NORMAL] here under, you must set clearlooks-framelessspinbutton -> base[NORMAL] to the very same value + bg[NORMAL] = shade (1.02, @rt_bg_color) + bg[ACTIVE] = shade (0.80, @rt_bg_color) +} + +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.93, @rt_bg_color) + bg[PRELIGHT] = shade (0.85, @rt_bg_color) + bg[ACTIVE] = shade (0.70, @rt_bg_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" { + + fg[NORMAL] = @rt_salt_pinch + fg[PRELIGHT] = @rt_salt_pinch + fg[INSENSITIVE] = @rt_salt_pinch + + 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 + + engine "clearlooks" { + hint = "expander" + } +} + +style "clearlooks-expanderLabel" { + + fg[NORMAL] = "#a0a0a0" + fg[PRELIGHT] = "#d0d0d0" +} + +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-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 "GtkExpander" style "clearlooks-expander" +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-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-expanderLabel" +widget_class "*.." style "clearlooks-expanderLabel" + +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_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 "*.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" + +# 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..e26b0efaa --- /dev/null +++ b/rtdata/themes/25-Gray-Red.gtkrc @@ -0,0 +1,486 @@ +# +# 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" + +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 = 18 + GtkExpander::expander-spacing = 0 + 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-framelessspinbutton" { + + # IMPORTANT! + # base[NORMAL] must have the same color than notebook bg[NORMAL] + base[NORMAL] = shade (1.02, @rt_bg_color) +} + +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" { + + bg[ACTIVE] = shade (1.40, @rt_bg_color) + bg[PRELIGHT] = shade (1.70, @rt_bg_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" { + + # IMPORTANT! + # If you modify bg[NORMAL] here under, you must set clearlooks-framelessspinbutton -> base[NORMAL] to the very same value + bg[NORMAL] = shade (1.02, @rt_bg_color) + bg[ACTIVE] = shade (0.80, @rt_bg_color) +} + +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.93, @rt_bg_color) + bg[PRELIGHT] = shade (0.85, @rt_bg_color) + bg[ACTIVE] = shade (0.70, @rt_bg_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" { + + fg[NORMAL] = @rt_salt_pinch + fg[PRELIGHT] = @rt_salt_pinch + fg[INSENSITIVE] = @rt_salt_pinch + + 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 + + engine "clearlooks" { + hint = "expander" + } +} + +style "clearlooks-expanderLabel" { + + fg[NORMAL] = "#a0a0a0" + fg[PRELIGHT] = "#d0d0d0" +} + +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-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 "GtkExpander" style "clearlooks-expander" +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-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-expanderLabel" +widget_class "*.." style "clearlooks-expanderLabel" + +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_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 "*.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" + +# 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..062e8d709 --- /dev/null +++ b/rtdata/themes/37-Gray-Red-Textured.gtkrc @@ -0,0 +1,835 @@ +# +# 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:#B2B2B2\nrt_tooltip_fg_color:#A5A5A5\nrt_selected_bg_color:#562020\nrt_selected_fg_color:#E2E2E2\nrt_text_color:#000000\nrt_bg_color:#5F5F5F\nrt_tooltip_bg_color:#404040" + +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 = 18 + GtkExpander::expander-spacing = 0 + 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_text_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_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-framelessspinbutton" { + + # IMPORTANT! + # base[NORMAL] must have the same color than notebook bg[NORMAL] + base[NORMAL] = @rt_bg_color +} + +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" { + + bg[ACTIVE] = shade (1.20, @rt_bg_color) + bg[PRELIGHT] = shade (1.50, @rt_bg_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" { + + # IMPORTANT! + # If you modify bg[NORMAL] here under, you must set clearlooks-framelessspinbutton -> base[NORMAL] to the very same value + bg[NORMAL] = @rt_bg_color + bg[ACTIVE] = shade (0.85, @rt_bg_color) +} + +style "clearlooks-combobox" { + + text[NORMAL] = @rt_fg_color + text[PRELIGHT] = @rt_selected_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_bg_color) + bg[PRELIGHT] = shade (0.85, @rt_bg_color) + bg[ACTIVE] = shade (0.70, @rt_bg_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" { + + fg[NORMAL] = @rt_salt_pinch + fg[PRELIGHT] = @rt_salt_pinch + fg[INSENSITIVE] = @rt_salt_pinch + + 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 + + engine "clearlooks" { + hint = "expander" + } +} + +style "clearlooks-expanderLabel" { + + fg[NORMAL] = @rt_text_color + fg[PRELIGHT] = lighter (@rt_fg_color) +} + +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-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 "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 "GtkExpander" style "clearlooks-expander" +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-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-expanderLabel" +widget_class "*.." style "clearlooks-expanderLabel" + +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_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 "*.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" + +# 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..abaaef6ab --- /dev/null +++ b/rtdata/themes/37-Gray-Red.gtkrc @@ -0,0 +1,487 @@ +# +# 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:#B2B2B2\nrt_tooltip_fg_color:#A5A5A5\nrt_selected_bg_color:#562020\nrt_selected_fg_color:#E2E2E2\nrt_text_color:#000000\nrt_bg_color:#5F5F5F\nrt_tooltip_bg_color:#404040" + +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 = 18 + GtkExpander::expander-spacing = 0 + 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_text_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_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-framelessspinbutton" { + + # IMPORTANT! + # base[NORMAL] must have the same color than notebook bg[NORMAL] + base[NORMAL] = @rt_bg_color +} + +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" { + + bg[ACTIVE] = shade (1.20, @rt_bg_color) + bg[PRELIGHT] = shade (1.50, @rt_bg_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" { + + # IMPORTANT! + # If you modify bg[NORMAL] here under, you must set clearlooks-framelessspinbutton -> base[NORMAL] to the very same value + bg[NORMAL] = @rt_bg_color + bg[ACTIVE] = shade (0.85, @rt_bg_color) +} + +style "clearlooks-combobox" { + + text[NORMAL] = @rt_fg_color + text[PRELIGHT] = @rt_selected_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_bg_color) + bg[PRELIGHT] = shade (0.85, @rt_bg_color) + bg[ACTIVE] = shade (0.70, @rt_bg_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" { + + fg[NORMAL] = @rt_salt_pinch + fg[PRELIGHT] = @rt_salt_pinch + fg[INSENSITIVE] = @rt_salt_pinch + + 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 + + engine "clearlooks" { + hint = "expander" + } +} + +style "clearlooks-expanderLabel" { + + fg[NORMAL] = @rt_text_color + fg[PRELIGHT] = lighter (@rt_fg_color) +} + +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-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 "GtkExpander" style "clearlooks-expander" +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-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-expanderLabel" +widget_class "*.." style "clearlooks-expanderLabel" + +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_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 "*.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" + +# 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..2db17e4f2 --- /dev/null +++ b/rtdata/themes/63-Gray-Cyan.gtkrc @@ -0,0 +1,487 @@ +# +# 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" + +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 = 18 + GtkExpander::expander-spacing = 0 + 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-framelessspinbutton" { + + # IMPORTANT! + # base[NORMAL] must have the same color than notebook bg[NORMAL] + base[NORMAL] = shade (1.05, @rt_bg_color) +} + +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" { + + bg[ACTIVE] = shade (1.15, @rt_bg_color) + bg[PRELIGHT] = shade (1.40, @rt_bg_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" { + + # IMPORTANT! + # If you modify bg[NORMAL] here under, you must set clearlooks-framelessspinbutton -> base[NORMAL] to the very same value + bg[NORMAL] = shade (1.05, @rt_bg_color) + bg[ACTIVE] = shade (0.92, @rt_bg_color) +} + +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) + + 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" { + + fg[NORMAL] = mix (0.6, @rt_selected_bg_color, @rt_text_color) + fg[PRELIGHT] = mix (0.6, @rt_selected_bg_color, @rt_text_color) + fg[INSENSITIVE] = @rt_selected_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 + + engine "clearlooks" { + hint = "expander" + } +} + +style "clearlooks-expanderLabel" { + + fg[NORMAL] = @rt_text_color + fg[PRELIGHT] = @rt_text_color +} + +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 "GtkExpander" style "clearlooks-expander" +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-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-expanderLabel" +widget_class "*.." style "clearlooks-expanderLabel" + +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_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 "*.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" + +# 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..83615a2a7 --- /dev/null +++ b/rtdata/themes/92-Beige-DarkCyan.gtkrc @@ -0,0 +1,476 @@ +# +# 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" + +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 = 18 + GtkExpander::expander-spacing = 0 + 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-framelessspinbutton" { + + # IMPORTANT! + # base[NORMAL] must have the same color than notebook bg[NORMAL] + base[NORMAL] = shade (1.02, @rt_bg_color) +} + +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" { + + bg[ACTIVE] = shade (1.15, @rt_bg_color) + bg[PRELIGHT] = shade (1.40, @rt_bg_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" { + + # IMPORTANT! + # If you modify bg[NORMAL] here under, you must set clearlooks-framelessspinbutton -> base[NORMAL] to the very same value + bg[NORMAL] = shade (1.02, @rt_bg_color) +} + +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) + + 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" { + + fg[NORMAL] = @rt_selected_bg_color + fg[PRELIGHT] = @rt_selected_bg_color + fg[INSENSITIVE] = @rt_selected_bg_color + + bg[PRELIGHT] = mix (0.20, @rt_selected_bg_color, @rt_bg_color) + + base[NORMAL] = @rt_selected_bg_color + base[PRELIGHT] = @rt_selected_bg_color + base[INSENSITIVE] = @rt_selected_bg_color + + engine "clearlooks" { + hint = "expander" + } +} + +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 "GtkExpander" style "clearlooks-expander" +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-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-expanderLabel" +widget_class "*.." style "clearlooks-expanderLabel" + +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_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 "*.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" + +# 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/Default.gtkrc b/rtdata/themes/Default.gtkrc new file mode 100644 index 000000000..e01fd39d0 --- /dev/null +++ b/rtdata/themes/Default.gtkrc @@ -0,0 +1,429 @@ +# +# 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:#000000\nrt_tooltip_fg_color:#000000\nrt_selected_bg_color:#86ABD9\nrt_selected_fg_color:#ffffff\nrt_text_color:#1A1A1A\nrt_bg_color:#EDECEB\nrt_tooltip_bg_color:#F5F5B5" + +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-length = 23 + GtkScale::trough-side-details = 0 + + GtkScrollbar::min-slider-length = 30 + GtkMenuBar::internal-padding = 0 + GtkExpander::expander-size = 16 + GtkToolbar::internal-padding = 1 + GtkTreeView::expander-size = 14 + 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] = darker (@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-HSV" { + + engine "clearlooks" { + hint = "HSV" + disable_focus = TRUE + } +} + +style "clearlooks-spinbutton" { + + engine "clearlooks" { + hint = "spinbutton" + } +} + +style "clearlooks-framelessspinbutton" { + + # IMPORTANT! + # base[NORMAL] must have the same color than notebook bg[NORMAL] + base[NORMAL] = shade (1.02, @rt_bg_color) +} + +style "clearlooks-scale" { + xthickness = 2 + ythickness = 2 + + engine "clearlooks" { + hint = "scale" + } +} + +style "clearlooks-thresholdselector" { + + bg[ACTIVE] = shade (1.15, @rt_bg_color) + bg[PRELIGHT] = shade (1.25, @rt_bg_color) +} + +style "clearlooks-vscale" { + + engine "clearlooks" { + hint = "vscale" + } +} + +style "clearlooks-hscale" { + + engine "clearlooks" { + hint = "hscale" + } +} + +style "clearlooks-scrollbar" { + xthickness = 2 + ythickness = 2 + + engine "clearlooks" { + hint = "scrollbar" + } +} + +style "clearlooks-hscrollbar" { + + engine "clearlooks" { + hint = "hscrollbar" + } +} + +style "clearlooks-vscrollbar" { + + engine "clearlooks" { + hint = "vscrollbar" + } +} + +style "clearlooks-notebook_bg" { + + # IMPORTANT! + # If you modify bg[NORMAL] here under, you must set clearlooks-framelessspinbutton -> base[NORMAL] to the very same value + bg[NORMAL] = shade (1.02, @rt_bg_color) +} + +style "clearlooks-combobox" { + + text[NORMAL] = @rt_fg_color + text[PRELIGHT] = @rt_fg_color + text[SELECTED] = @rt_selected_fg_color + text[INSENSITIVE] = darker (@rt_bg_color) + text[ACTIVE] = @rt_fg_color +} + +style "clearlooks-button" { + xthickness = 3 + ythickness = 3 + + bg[NORMAL] = shade (1.04, @rt_bg_color) + bg[PRELIGHT] = shade (1.06, @rt_bg_color) + bg[ACTIVE] = shade (0.85, @rt_bg_color) +} + +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-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" { + + 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 "GtkEntry" style "clearlooks-entry" + +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-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-expanderLabel" +widget_class "*.." style "clearlooks-expanderLabel" + +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_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 "*.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" + +# 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/Default.iconset b/rtdata/themes/Default.iconset new file mode 100644 index 000000000..c7116f4a2 --- /dev/null +++ b/rtdata/themes/Default.iconset @@ -0,0 +1,3 @@ +[General] +Iconset=Light +FallbackIconset= 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..05da5df06 --- /dev/null +++ b/rtdata/themes/slim @@ -0,0 +1,131 @@ +# +# 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 = 11 + 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-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..c55288926 --- /dev/null +++ b/rtdata/win/InnoSetup/WindowsInnoSetup.iss.in @@ -0,0 +1,130 @@ +; 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}\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 +; 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..d43fc41bb --- /dev/null +++ b/rtengine/CA_correct_RT.cc @@ -0,0 +1,1041 @@ +//////////////////////////////////////////////////////////////// +// +// 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;} } + + 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 polymat[3][2][256], shiftmat[3][2][16], fitparams[3][2][16]; + for (int i=0; i<256; i++) {polymat[0][0][i] = polymat[0][1][i] = polymat[2][0][i] = polymat[2][1][i] = 0;} + for (int i=0; i<16; i++) {shiftmat[0][0][i] = shiftmat[0][1][i] = shiftmat[2][0][i] = shiftmat[2][1][i] = 0;} + + //order of 2d polynomial fit (polyord), and numpar=polyord^2 + int polyord=4, numpar=16; + int numblox[3]={0,0,0}; + +#pragma omp parallel shared(Gtmp,width,height,blockave,blocksqave,blockdenom,blockvar,blockwt,blockshifts,polymat,shiftmat,fitparams,polyord,numpar) +{ + int progresscounter = 0; + //number of blocks used in the fit + int numbloxthr[3]={0,0,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) { +#pragma omp sections +{ +#pragma omp section + for (vblock=1; vblock4.0*blockvar[0][c] || SQR(bstemp[c][1])>4.0*blockvar[1][c]) + continue; + numbloxthr[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..03f339f97 --- /dev/null +++ b/rtengine/CMakeLists.txt @@ -0,0 +1,41 @@ +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 + 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 + EdgePreserveLab.cc EdgePreservingDecomposition.cc cplx_wavelet_dec.cc FTblockDN.cc + PF_correct_RT.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 + ) + +include_directories (BEFORE "${CMAKE_CURRENT_BINARY_DIR}") + +add_library (rtengine ${RTENGINESOURCEFILES}) +#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 "${BINDIR}" 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..38267e957 --- /dev/null +++ b/rtengine/EdgePreservingDecomposition.cc @@ -0,0 +1,768 @@ +#include +#include "rt_math.h" +#include "EdgePreservingDecomposition.h" +#ifdef _OPENMP +#include +#endif +#include "sleef.c" +#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; + } + } + + StartRows[index] = StartRow; + memset(Diagonals[index], 0, sizeof(float)*DiagonalLength(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; +} + +void MultiDiagonalSymmetricMatrix::VectorProduct(float* RESTRICT Product, float* RESTRICT x){ + + //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) +#ifdef _OPENMP +#pragma omp parallel for +#endif + for(int j = 0; 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= icn - icStartRows[s]) 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] = sss < 0 ? temp * id : (Diagonals[sss][j] + temp) * id; + } + } + 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; j 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=1;iCreateDiagonal(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 ); + __m128 temp1v, temp2v; +#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){ + //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; + +#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 100644 index 000000000..93dccbfa4 --- /dev/null +++ b/rtengine/EdgePreservingDecomposition.h @@ -0,0 +1,137 @@ +#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 "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..7ddb6835a --- /dev/null +++ b/rtengine/FTblockDN.cc @@ -0,0 +1,1309 @@ +//////////////////////////////////////////////////////////////// +// +// 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 "bilateral2.h" +#include "gauss.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" +#ifdef __SSE2__ + #include "sleefsseavx.c" +#endif + +#ifdef _OPENMP +#include +#endif + +#include "cplx_wavelet_dec.h" + +//#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 TS 64 // Tile size +#define offset 25 // shift between tiles +#define fTS ((TS/2+1)) // second dimension of Fourier tiles +#define blkrad 1 // radius of block averaging + +#define epsilon 0.001f/(TS*TS) //tolerance + +namespace rtengine { + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + /* + 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; + + + + + void ImProcFunctions::RGB_denoise(Imagefloat * src, Imagefloat * dst, bool isRAW, const procparams::DirPyrDenoiseParams & dnparams, const procparams::DefringeParams & defringe, const double expcomp) + { +//#ifdef _DEBUG +// MyTime t1e,t2e; +// t1e.set(); +//#endif + + static MyMutex FftwMutex; + MyMutex::MyLock lock(FftwMutex); + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + /*if (plistener) { + plistener->setProgressStr ("Denoise..."); + plistener->setProgress (0.0); + }*/ + +// volatile double progress = 0.0; + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + const short int imheight=src->height, imwidth=src->width; + + if (dnparams.luma==0 && dnparams.chroma==0) { + //nothing to do; copy src to dst + memcpy(dst->data,src->data,dst->width*dst->height*3*sizeof(float)); + return; + } + perf=false; + if(dnparams.dmethod=="RGB") perf=true;//RGB mode + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // 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,0); + if(perf) { + 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,0); + if(perf) { + 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); + } + + } + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + //srand((unsigned)time(0));//test with random data + + const float gain = pow (2.0f, float(expcomp)); + float incr=1.f; + float noisevar_Ldetail = SQR((SQR(100.f-dnparams.Ldetail) + 50.f*(100.f-dnparams.Ldetail)) * TS * 0.5f * incr); + bool enhance_denoise = dnparams.enhance; + noisered=1.f;//chroma red + if(dnparams.redchro<-0.1f) {noisered=0.001f+SQR((100.f + dnparams.redchro)/100.0f);} + else if(dnparams.redchro>0.1f) {noisered=1.f+SQR((dnparams.redchro));} + else if (dnparams.redchro>= -0.1f && dnparams.redchro<=0.1f) noisered=0.f; + + noiseblue=1.f;//chroma blue + if(dnparams.bluechro<-0.1f) {noiseblue=0.001f+SQR((100.f + dnparams.bluechro)/100.0f);} + else if(dnparams.bluechro>0.1f) {noiseblue=1.f+SQR((dnparams.bluechro));} + else if (dnparams.bluechro>= -0.1f && dnparams.bluechro<=0.1f) noiseblue=0.f; + + array2D tilemask_in(TS,TS); + array2D tilemask_out(TS,TS); + + const int border = MAX(2,TS/16); + +#ifdef _OPENMP +#pragma omp parallel for +#endif + for (int i=0; iTS/2 ? i-TS+1 : i)); + float vmask = (i1TS/2 ? j-TS+1 : j)); + tilemask_in[i][j] = (vmask * (j1data[n] = 0; + + const int tilesize = 1024; + const int overlap = 128; + + int numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip; + + if (imwidth 0) numthreads = MIN(numthreads,options.rgbDenoiseThreadLimit); + // Issue 1887, overide setting of 1, if more than one thread is available. This way the inner omp-directives should become inactive + if(numthreads == 1 && omp_get_max_threads() > 1) + numthreads = 2; +#pragma omp parallel num_threads(numthreads) +#endif + { + //DCT block data storage + float * Lblox; + float * fLblox; + 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); + //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]} + }; + + + +#ifdef _OPENMP +#pragma omp critical +#endif + { + Lblox = (float*) fftwf_malloc(max_numblox_W*TS*TS*sizeof(float)); + fLblox = (float*) fftwf_malloc(max_numblox_W*TS*TS*sizeof(float)); + } +#ifdef _OPENMP +#pragma omp for schedule(dynamic) collapse(2) +#endif + for (int tiletop=0; tiletop Lin(width,height); + //wavelet denoised image + LabImage * labdn = new LabImage(width,height); + + //residual between input and denoised L channel + array2D Ldetail(width,height,ARRAY2D_CLEAR_DATA); + //pixel weight + array2D totwt(width,height,ARRAY2D_CLEAR_DATA);//weight for combining DCT blocks + + // + + //#ifdef _OPENMP + //#pragma omp parallel for + //#endif + //TODO: implement using AlignedBufferMP + //fill tile from image; convert RGB to "luma/chroma" + if (isRAW) {//image is raw; use channel differences for chroma channels + if(!perf){//lab mode + for (int i=tiletop/*, i1=0*/; ir(i,j); + float G_ = gain*src->g(i,j); + float B_ = gain*src->b(i,j); + //modify arbitrary data for Lab..I have test : nothing, gamma standard, gamma SRGB and GammaBT709... + //we can put other as gamma g=2.6 slope=11, etc. + // Gamma sRGB is a good compromise, but noting to do with real gamma !!!: it's only for data Lab # data RGB + //finally I opted fot gamma_26_11 + R_ = Color::igammatab_26_11[R_]; + G_ = Color::igammatab_26_11[G_]; + B_ = Color::igammatab_26_11[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 L,a,b; + float X,Y,Z; + Color::rgbxyz(R_,G_,B_,X,Y,Z,wp); + + //convert to Lab + Color::XYZ2Lab(X, Y, Z, L, a, b); + labdn->L[i1][j1] = L; + labdn->a[i1][j1] = a; + labdn->b[i1][j1] = b; + Lin[i1][j1] = L; +// totwt[i1][j1] = 0; + } + } + } + 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->L[i1][j1] = Y; + labdn->a[i1][j1] = (X-Y); + labdn->b[i1][j1] = (Y-Z); + +// Ldetail[i1][j1] = 0; + Lin[i1][j1] = Y; +// totwt[i1][j1] = 0; + } + } + + } + } else {//image is not raw; use Lab parametrization + for (int i=tiletop/*, i1=0*/; i 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; + +// Ldetail[i1][j1] = 0; + Lin[i1][j1] = L; + +// totwt[i1][j1] = 0; + } + } + } + + + //initial impulse denoise + if (dnparams.luma>0.01) { + impulse_nr (labdn, MIN(50.0f,dnparams.luma)/20.0f); + } + + 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. + float noisevarL = SQR((dnparams.luma/125.0f)*(1+ dnparams.luma/25.0f)); + + float interm_med= dnparams.chroma/10.0f; + float intermred, intermblue; + if(dnparams.redchro > 0.f) intermred=0.0014f*SQR(dnparams.redchro); else intermred= dnparams.redchro/7.0f;//increase slower than linear for more sensit + float intermred2=dnparams.redchro/7.0f; + if(dnparams.bluechro > 0.f) intermblue=0.0014f*SQR(dnparams.bluechro); else intermblue= dnparams.bluechro/7.0f;//increase slower than linear + float intermblue2=dnparams.bluechro/7.0f; + //adjust noise ab in function of sliders red and blue + float realred = interm_med + intermred; if (realred < 0.f) realred=0.01f; + float realred2 = interm_med + intermred2; if (realred2 < 0.f) realred2=0.01f; + float noisevarab_r = SQR(realred); + float realblue = interm_med + intermblue; if (realblue < 0.f) realblue=0.01f; + float realblue2 = interm_med + intermblue2; if (realblue2 < 0.f) realblue2=0.01f; + float noisevarab_b = SQR(realblue); + + + { // enclosing this code in a block frees about 120 MB before allocating 20 MB after this block (measured with D700 NEF) + wavelet_decomposition* Ldecomp; + wavelet_decomposition* adecomp; + wavelet_decomposition* bdecomp; + + int levwav=5; + float maxreal = max(realred2, realblue2); + //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 (settings->verbose) printf("levwavelet=%i noisevarA=%f noisevarB=%f \n",levwav, noisevarab_r, noisevarab_b ); + Ldecomp = new wavelet_decomposition (labdn->data, labdn->W, labdn->H, levwav/*maxlevels*/, 0/*subsampling*/ ); + adecomp = new wavelet_decomposition (labdn->data+datalen, labdn->W, labdn->H,levwav, 1 ); + bdecomp = new wavelet_decomposition (labdn->data+2*datalen, labdn->W, labdn->H, levwav, 1 ); + + if(enhance_denoise) WaveletDenoiseAll_BiShrink(*Ldecomp, *adecomp, *bdecomp, noisevarL, noisevarab_r, noisevarab_b,labdn);//enhance mode + else; WaveletDenoiseAll(*Ldecomp, *adecomp, *bdecomp, noisevarL, noisevarab_r, noisevarab_b,labdn);// + + Ldecomp->reconstruct(labdn->data); + delete Ldecomp; + adecomp->reconstruct(labdn->data+datalen); + delete adecomp; + bdecomp->reconstruct(labdn->data+2*datalen); + delete bdecomp; + } + + //TODO: at this point wavelet coefficients storage can be freed + //Issue 1680: Done now + + //second impulse denoise + if (dnparams.luma>0.01) { + impulse_nr (labdn, MIN(50.0f,dnparams.luma)/20.0f); + } + //PF_correct_RT(dst, dst, defringe.radius, defringe.threshold); + + //wavelet denoised L channel + array2D Lwavdn(width,height); + float * Lwavdnptr = Lwavdn; + memcpy (Lwavdnptr, labdn->data, width*height*sizeof(float)); + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // now do detail recovery using block DCT to detect + // patterns missed by wavelet denoise + // blocks are not the same thing as tiles! + + + + // calculation for detail recovery blocks + const int numblox_W = ceil(((float)(width))/(offset))+2*blkrad; + const int numblox_H = ceil(((float)(height))/(offset))+2*blkrad; + + //const int nrtiles = numblox_W*numblox_H; + // end of tiling calc + { + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // Main detail recovery algorithm: Block loop + //OpenMP here + //adding omp here leads to artifacts + AlignedBuffer pBuf(width + TS + 2*blkrad*offset); + for (int vblk=0; vblk=height) { + rr = MAX(0,2*height-2-row); + } + + for (int j=0; jW; j++) { + datarow[j] = (Lin[rr][j]-Lwavdn[rr][j]); + } + + for (int j=-blkrad*offset; j<0; j++) { + datarow[j] = datarow[MIN(-j,width-1)]; + } + for (int j=width; j=0 && top+i=0 && left+jL[i][j] = Lwavdn[i][j] + hpdn; + + } + } + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // transform denoised "Lab" to output RGB + + //calculate mask for feathering output tile overlaps + float * Vmask = new float [height+1]; + float * Hmask = new float [width+1]; + + for (int i=0; i0) Vmask[i] = mask; + if (tilebottom0) Hmask[i] = mask; + if (tilerightxyz + L = labdn->L[i1][j1]; + a = labdn->a[i1][j1]; + b = labdn->b[i1][j1]; + //convert XYZ + 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.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); + //readapt arbitrary gamma (inverse from beginning) + r_ = Color::gammatab_26_11[r_]; + g_ = Color::gammatab_26_11[g_]; + b_ = Color::gammatab_26_11[b_]; + + float factor = Vmask[i1]*Hmask[j1]/gain; + + dsttmp->r(i,j) += factor*r_; + dsttmp->g(i,j) += factor*g_; + dsttmp->b(i,j) += factor*b_; + + } + } + } + else {//RGB mode + for (int i=tiletop; iL[i1][j1]; + X = (labdn->a[i1][j1]) + Y; + 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); + + float factor = Vmask[i1]*Hmask[j1]/gain; + + dsttmp->r(i,j) += factor*X; + dsttmp->g(i,j) += factor*Y; + dsttmp->b(i,j) += factor*Z; + + } + } + + } + } else { +#ifdef _OPENMP +//#pragma omp parallel for +#endif + for (int i=tiletop; iL[i1][j1]; + a = labdn->a[i1][j1]; + b = labdn->b[i1][j1]; + Color::Lab2XYZ(L, a, b, X, Y, Z); + + float factor = Vmask[i1]*Hmask[j1]; + 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); + + dsttmp->r(i,j) += factor*r_; + dsttmp->g(i,j) += factor*g_; + dsttmp->b(i,j) += factor*b_; + + } + } + } + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + delete labdn; + // delete noiseh; + + delete[] Vmask; + delete[] Hmask; + + + + }//end of tile row + }//end of tile loop +#ifdef _OPENMP +#pragma omp critical +#endif +{ + fftwf_free ( Lblox); + fftwf_free ( fLblox); +} + + } + //copy denoised image to output + memcpy (dst->data, dsttmp->data, 3*dst->width*dst->height*sizeof(float)); + + if (!isRAW) {//restore original image gamma +#ifdef _OPENMP +#pragma omp parallel for +#endif + for (int i=0; i<3*dst->width*dst->height; i++) { + dst->data[i] = Color::gammatab_srgb[ dst->data[i] ]; + } + } + + delete dsttmp; + + // 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(); +//#ifdef _DEBUG +// if (settings->verbose) { +// t2e.set(); +// printf("Denoise performed in %d usec:\n", t2e.etime(t1e)); +// } +//#endif + + }//end of main RGB_denoise + + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +#if defined( __SSE2__ ) && defined( WIN32 ) +__attribute__((force_align_arg_pointer)) void ImProcFunctions::RGBtile_denoise (float * fLblox, int vblproc, int hblproc, int numblox_H, int numblox_W, float noisevar_Ldetail ) //for DCT +#else + void ImProcFunctions::RGBtile_denoise (float * fLblox, int vblproc, int hblproc, int numblox_H, int numblox_W, float noisevar_Ldetail ) //for DCT +#endif + { + float * nbrwt = new float[TS*TS]; //for DCT + int blkstart = hblproc*TS*TS; + + boxabsblur(fLblox+blkstart, nbrwt, 3, 3, TS, TS);//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; n=0; lvl--) {//for levels less than max, use level diff to make edge mask + //for (int lvl=0; lvl edge(Wlvl_L,Hlvl_L); + + //printf("\n level=%d \n",lvl); + + for (int dir=1; dir<4; dir++) { + float mad_L = madL[lvl][dir-1]; + float mad_a = noisevar_abr*mada[lvl][dir-1]; + float mad_b = noisevar_abb*madb[lvl][dir-1]; + //float mad_Lpar = madL[lvl+1][dir-1]; + //float mad_apar = mada[lvl+1][dir-1]; + //float mad_bpar = mada[lvl+1][dir-1]; + + //float skip_ab_ratio = WaveletCoeffs_a.level_stride(lvl+1)/skip_ab; + float skip_L_ratio = WaveletCoeffs_L.level_stride(lvl+1)/skip_L; + + if (noisevar_abr>0.01) { + + //printf(" dir=%d mad_L=%f mad_a=%f mad_b=%f \n",dir,sqrt(mad_L),sqrt(mad_a),sqrt(mad_b)); + +//OpenMP here + for (int i=0; i2 ? 1 : (coeff_a<1 ? 0 : (coeff_a - 1))); + //WavCoeffs_b[dir][coeffloc_ab] *= edgefactor*(coeff_b>2 ? 1 : (coeff_b<1 ? 0 : (coeff_b - 1))); + + //float satfactor_a = mad_a/(mad_a+0.5*SQR(WavCoeffs_a[0][coeffloc_ab])); + //float satfactor_b = mad_b/(mad_b+0.5*SQR(WavCoeffs_b[0][coeffloc_ab])); + + WavCoeffs_a[dir][coeffloc_ab] *= SQR(1-xexpf(-(mag_a/mad_a)-(mag_L/(9*mad_L)))/*satfactor_a*/); + WavCoeffs_b[dir][coeffloc_ab] *= SQR(1-xexpf(-(mag_b/mad_b)-(mag_L/(9*mad_L)))/*satfactor_b*/); + + } + }//now chrominance coefficients are denoised + } + + if (noisevar_L>0.01) { + mad_L *= noisevar_L*5/(lvl+1); +//OpenMP here + for (int i=0; i (edge, edge, buffer, Wlvl_L, Hlvl_L, 1<<(lvl+1), false /*multiThread*/); + //gaussVertical (edge, edge, buffer, Wlvl_L, Hlvl_L, 1<<(lvl+1), false); + + boxblur(sfave, sfave, lvl+2, lvl+2, Wlvl_L, Hlvl_L);//increase smoothness by locally averaging shrinkage +//OpenMP here + for (int i=0; i 582=max + float mad_b = madb*noisevar_abb; + + if (noisevar_abr>0.01 || noisevar_abb>0.01) { +//OpenMP here + +#ifdef _OPENMP +#pragma omp parallel for +#endif + for (int i=0; ib[2*i][2*j],noi->a[2*i][2*j]); + float hh =xatan2(WavCoeffs_b[dir][coeffloc_ab],WavCoeffs_a[dir][coeffloc_ab]); + //one can also use L or c (chromaticity) if necessary + // if(hh > -0.4f && hh < 1.6f) reduc=noisered;//red from purple to next yellow + // if(hh>-2.45f && hh <=-0.4f) bluuc=noiseblue;//blue + if(hh>1.3f && hh <=2.2f) bluuc=noiseblue;//blue + } + + mad_a*=reduc; + mad_a*=bluuc; + mad_b*=reduc; + mad_b*=bluuc; + */ + float mag_L = SQR(WavCoeffs_L[dir][coeffloc_L ])+eps; + float mag_a = SQR(WavCoeffs_a[dir][coeffloc_ab])+eps; + float mag_b = SQR(WavCoeffs_b[dir][coeffloc_ab])+eps; + sfavea[coeffloc_ab] = (1.f-xexpf(-(mag_a/mad_a)-(mag_L/(9.f*madL)))); + sfaveb[coeffloc_ab] = (1.f-xexpf(-(mag_b/mad_b)-(mag_L/(9.f*madL)))); + mad_a=m_a; + mad_b=m_b; + // 'firm' threshold of chroma coefficients + //WavCoeffs_a[dir][coeffloc_ab] *= (1-exp(-(mag_a/mad_a)-(mag_L/(9*madL))));//(coeff_a>2*thresh_a ? 1 : (coeff_a2*thresh_b ? 1 : (coeff_bb[2*i][2*j],noi->a[2*i][2*j]); + float hh =xatan2(WavCoeffs_b[dir][coeffloc_ab],WavCoeffs_a[dir][coeffloc_ab]); + + // if(hh > -0.4f && hh < 1.6f) reduc=noisered; + // if(hh>-2.45f && hh <=-0.4f) bluuc=noiseblue; + if(hh>1.3f && hh <=2.2f) bluuc=noiseblue;//blue + + } + + mad_a*=reduc; + mad_a*=bluuc; + mad_b*=reduc; + mad_b*=bluuc; + */ + float mag_L = SQR(WavCoeffs_L[dir][coeffloc_L ])+eps; + float mag_a = SQR(WavCoeffs_a[dir][coeffloc_ab])+eps; + float mag_b = SQR(WavCoeffs_b[dir][coeffloc_ab])+eps; + + float sfa = (1.f-xexpf(-(mag_a/mad_a)-(mag_L/(9.f*madL)))); + float sfb = (1.f-xexpf(-(mag_b/mad_b)-(mag_L/(9.f*madL)))); + + //use smoothed shrinkage unless local shrinkage is much less + WavCoeffs_a[dir][coeffloc_ab] *= (SQR(sfavea[coeffloc_ab])+SQR(sfa))/(sfavea[coeffloc_ab]+sfa+eps); + WavCoeffs_b[dir][coeffloc_ab] *= (SQR(sfaveb[coeffloc_ab])+SQR(sfb))/(sfaveb[coeffloc_ab]+sfb+eps); + mad_a=m_a; + mad_b=m_b; + + }//now chrominance coefficients are denoised + } + + if (noisevar_L>0.01) { +#ifdef __SSE2__ + __m128 magv; + __m128 mad_Lv = _mm_set1_ps( mad_L ); + __m128 ninev = _mm_set1_ps( 9.0f ); + __m128 epsv = _mm_set1_ps( eps ); + 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 + +template +class LUT { +private: + // list of variables ordered to improve cache speed + unsigned int maxs; + T * data; + unsigned int clip, size, 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; + maxs=size-2; +#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; + maxs=size-2; +#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; + maxs=size-2; +#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; + } + + 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->maxs=this->size-2; +#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 { + if (((unsigned int)index) maxs) { + if (idx<0) + { + if (clip & LUT_CLIP_BELOW) + return data[0]; + idx=0; + } + else + { + if (clip & LUT_CLIP_ABOVE) + return data[size - 1]; + 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; + maxs=0; + } +}; + +#endif /* LUT_H_ */ diff --git a/rtengine/PF_correct_RT.cc b/rtengine/PF_correct_RT.cc new file mode 100644 index 000000000..9e438b349 --- /dev/null +++ b/rtengine/PF_correct_RT.cc @@ -0,0 +1,1075 @@ +//////////////////////////////////////////////////////////////// +// +// 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" + +#ifdef __SSE2__ +#include "sleefsseavx.c" +#endif + +#ifdef _OPENMP +#include +#endif + +using namespace std; + +namespace rtengine { +extern const Settings* settings; + +#if defined( __SSE2__ ) && defined( WIN32 ) +__attribute__((force_align_arg_pointer)) void ImProcFunctions::PF_correct_RT(LabImage * src, LabImage * dst, double radius, int thresh) +#else +void ImProcFunctions::PF_correct_RT(LabImage * src, LabImage * dst, double radius, int thresh) +#endif +{ + 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 + double hr; + float chparam = float((chCurve->getVal((hr=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); +} +#if defined( __SSE2__ ) && defined( WIN32 ) +__attribute__((force_align_arg_pointer)) void ImProcFunctions::PF_correct_RTcam(CieImage * src, CieImage * dst, double radius, int thresh) +#else +void ImProcFunctions::PF_correct_RTcam(CieImage * src, CieImage * dst, double radius, int thresh) +#endif +{ + 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 + double hr; + float chparam = float((chCurve->getVal((hr=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; i(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 + +#if defined( __SSE2__ ) && defined( WIN32 ) +__attribute__((force_align_arg_pointer)) void ImProcFunctions::Badpixelscam(CieImage * src, CieImage * dst, double radius, int thresh, int mode) +#else +void ImProcFunctions::Badpixelscam(CieImage * src, CieImage * dst, double radius, int thresh, int mode) +#endif +{ + 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; 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 __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) { + 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++) { + 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++) { + 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 + } +} + + 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)); + + +} +} +#undef PIX_SORT +#undef med3 diff --git a/rtengine/StopWatch.h b/rtengine/StopWatch.h new file mode 100644 index 000000000..e43b90247 --- /dev/null +++ b/rtengine/StopWatch.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 . + * + * Author: reine + */ + +#ifndef STOPWATCH_H +#define STOPWATCH_H +#include +#include + +class StopWatch { +public: + StopWatch( ) { stopped = false; } + StopWatch( const char* msg) { message = msg; start(); stopped = false; } + ~StopWatch() { if(!stopped) stop(); } + void start() + { + gettimeofday(&startStruct,NULL); + }; + void stop() + { + gettimeofday(&stopStruct,NULL); + long elapsedTime = (stopStruct.tv_sec - startStruct.tv_sec) * 1000.0; // sec to ms + elapsedTime += (stopStruct.tv_usec - startStruct.tv_usec)/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; + +public: + T* data ; + bool inUse; + + /* size is the number of elements of size T, i.e. allocated size will be sizeof(T)*size ; set it to 0 if you want to defer the allocation + * align is 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), data(NULL), inUse(false) { + if (size) + resize(size); + } + + ~AlignedBuffer () { + if (real) free(real); + } + + /* Allocate the the "size" amount of elements of "structSize" length each + * params: + * @size: number of elements to allocate + * @structSize: if non null, will let you override the default struct's size (unit: byte) + */ + 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; + } + else { + int sSize = structSize ? structSize : sizeof(T); + allocatedSize = size*sSize; + real = realloc(real, 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; + 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; + } +}; + +// 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 (int i=0;i* acquire() { + MyMutex::MyLock lock(mtx); + + // Find available buffer + for (int i;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..165a17d3d --- /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::methodstring[RAWParams::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 + +} +} \ No newline at end of file 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" +#ifdef __SSE2__ + #include "sleefsseavx.c" +#endif + +//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 __attribute__((force_align_arg_pointer)) void boxblur (T* src, A* dst, int radx, int rady, int W, int H) { +#else +template void boxblur (T* src, A* dst, int radx, int rady, int W, int H) { +#endif +//printf("boxblur\n"); + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //box blur image; box range = (radx,rady) i.e. box size is (2*radx+1)x(2*rady+1) + + AlignedBuffer* buffer = new AlignedBuffer (W*H); + float* temp = buffer->data; + if (radx==0) { + for (int row=0; row 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 __attribute__((force_align_arg_pointer)) void boxabsblur (T* src, A* dst, int radx, int rady, int W, int H) { +#else +template void boxabsblur (T* src, A* dst, int radx, int rady, int W, int H) { +#endif + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //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 +#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..f71942265 --- /dev/null +++ b/rtengine/calc_distort.cc @@ -0,0 +1,227 @@ +/********************************************************************** +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 + +#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 + +double calcDistortion(unsigned char* img1, unsigned char* img2, int ncols, int nrows) +{ + KLT_TrackingContext tc; + KLT_FeatureList fl; + KLT_FeatureTable ft; + int i,n; + double radius, wc, hc; + + double r0[N_FEATURES] = {0.0}; + double r10[N_FEATURES] = {0.0}; + + 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); + ft = KLTCreateFeatureTable(2, N_FEATURES); + + 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"); + return 0.0; + } + + 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"); + return 0.0; + } + + 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"); + return 0.0; + } + + if (rxy < RXY_LIMIT) { + printf ("Not linear enough\n"); + return 0.0; + } + + printf ("distortion amount=%lf scale=%lf deviation=%lf, rxy=%lf\n", a, b, total_delta/n, rxy); + return a; +} + diff --git a/rtengine/calc_distort.h b/rtengine/calc_distort.h new file mode 100644 index 000000000..580c8915b --- /dev/null +++ b/rtengine/calc_distort.h @@ -0,0 +1,4 @@ +#ifndef CALC_DISTORTION__H +#define CALC_DISTORTION__H + double calcDistortion (unsigned char* img1, unsigned char* img2, int ncols, int nrows); +#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..803e33a56 --- /dev/null +++ b/rtengine/camconst.json @@ -0,0 +1,528 @@ +/* + + 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 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 + "raw_crop": [ 10, 20, 4000, 3000 ], + // same as MaskedAreas DNG tag, used for black level measuring here two areas defined + "masked_areas": [ 51, 2, 3804, 156, 51, 5794, 3804, 5792 ], + }, + + { + "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 10 - 20 units below, say at 15750 in +this example, 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-10/15760) = +-0.001 stop of detail, ie irrelevant. Thus it's better to provide RawTherapee +with knowledge where the image clips rather than keeping that last 0.001 stop +of highlight information and risking that clipping will not be detected +properly. + +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. + +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.1 stop down to f/1.4 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 wider margin here than on the +white levels, ie 0.5-1% lower or so. For example if base (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.02 or +2% to keep a +margin. + +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. + +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 (you need to start RT from a console to see +the output). 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 or 1024, 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 Nikon cameras), or +it can be derived from masked pixels (typical for Canon cameras) or otherwise +be extracted from some tag. Some formats are have built-in subtraction +information and are pre-processed by DCRaw to end up at a black level of zero +(Phase One's IIQ). 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 (which has a single black level around 512), 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 (only aperture scaling for f/1.2 missing) + "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": 15750 }, // typical: 15760 + { "iso": 100, "levels": 15750 }, + { "iso": 125, "levels": 15750 }, + { "iso": 160, "levels": 12800 }, + { "iso": 200, "levels": 15750 }, + { "iso": 250, "levels": 15750 }, + { "iso": 320, "levels": 12800 }, // typical: 12810 + { "iso": 400, "levels": 15750 }, + { "iso": 500, "levels": 15750 }, + { "iso": 640, "levels": 12800 }, + { "iso": 800, "levels": 15750 }, + { "iso": 1000, "levels": 15750 }, + { "iso": 1250, "levels": 12800 }, + { "iso": 1600, "levels": 15750 }, + { "iso": 2000, "levels": 15750 }, + { "iso": 2500, "levels": 15750 }, + { "iso": 3200, "levels": 15750 }, + { "iso": 4000, "levels": 15750 }, + { "iso": 5000, "levels": 15750 }, + { "iso": 6400, "levels": 16370 }, // typical: 16383 + { "iso": 12800, "levels": 16370 }, + { "iso": 25600, "levels": 16370 } + ], + "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 15750 white level maxes out at "white_max" for f/1.8 and below anyway. */ + { "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.0046 }, + { "aperture": 3.5, "scale_factor": 1.0031 } + ] + } + }, + { // quality B, more aperture scalings desired + "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, "levels": 15270 }, // typical: 15282 + { "iso": 100, "levels": 15270 }, + { "iso": 125, "levels": 15270 }, + { "iso": 160, "levels": 13300 }, // typical: 13306 + { "iso": 200, "levels": 15270 }, + { "iso": 250, "levels": 15270 }, + { "iso": 320, "levels": 13300 }, + { "iso": 400, "levels": 15270 }, + { "iso": 500, "levels": 15270 }, + { "iso": 640, "levels": 13300 }, + { "iso": 800, "levels": 15270 }, + { "iso": 1000, "levels": 15270 }, + { "iso": 1250, "levels": 13300 }, + { "iso": 1600, "levels": 15270 }, + { "iso": 2000, "levels": 15270 }, + { "iso": 2500, "levels": 13300 }, + { "iso": 3200, "levels": 15270 }, + { "iso": 4000, "levels": 15270 }, + { "iso": 5000, "levels": 13300 }, + { "iso": 6400, "levels": 15270 }, + { "iso": 8000, "levels": 15270 }, + { "iso": 10000, "levels": 13300 }, // no data, guessed + { "iso": 12800, "levels": 15270 }, + { "iso": 16000, "levels": 15270 }, + { "iso": 20000, "levels": 15270 }, + { "iso": 25600, "levels": 16300 }, + { "iso": 32000, "levels": 16300 }, + { "iso": 40000, "levels": 16300 }, + { "iso": 51200, "levels": 16300 }, + { "iso": 102400, "levels": 16300 } + ], + "white_max": 16383, + "aperture_scaling": [ + // limited scaling info available, please provide more + { "aperture": 2.0, "scale_factor": 1.024 }, + { "aperture": 2.8, "scale_factor": 1.010 } + ] + } + }, + + { // 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, // 16383 typical + 15760, // 15778 typical + 16370 // 16383 typical + ], + "white_max": 16383 + // aperture scaling not measured, but known to exist, at f/1.8 the G channels hits white_max + } + }, + + { // quality A + "make_model": "Sony SLT-A77", + "dcraw_matrix": [ 5126,-830,-261,-4788,12196,2934,-948,1602,7068 ], // matrix provided by Colin Walker + // note: Sony ARW2 file format gets 14 bit values, not 12 bit like in dcraw 9.19 + "ranges": { "black": 512, "white": 16350 } + }, + { // quality A + "make_model": [ "Sony SLT-A99", "Sony SLT-A99V" ], + "dcraw_matrix": [ 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 ], + "ranges": { "black": 512, "white": 16350 } + }, + + /* 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", "Phase One P65+", "Phase One IQ160" ], + "dcraw_matrix": [ 8035,435,-962,-6001,13872,2320,-1159,3065,5434 ], + "ranges": { "black": 0, "white": 63300 } + }, + { // quality A + "make_model": [ "Phase One IQ180", "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 } + }, + + // 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/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/color.cc b/rtengine/color.cc new file mode 100644 index 000000000..ab52fc73c --- /dev/null +++ b/rtengine/color.cc @@ -0,0 +1,2863 @@ +/* +* This file is part of RawTherapee. +* +* Copyright (c) 2004-2010 Gabor Horvath +* +* RawTherapee is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* RawTherapee is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU 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" + +using namespace std; + +namespace rtengine { + + extern const Settings* settings; + + 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_26_11; + LUTf Color::gammatab_26_11; + LUTf Color::igammatab_24_17; + LUTf Color::gammatab_24_17a; + + // 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::kappa=903.29630; //24389.0/27.0; + + const float Color::D50x=0.96422; + const float Color::D50z=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,0/*LUT_CLIP_BELOW*/); + + gamma2curve(maxindex,0); + + 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::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; // 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 - s ); + float q = v * ( 1 - s * f ); + float t = v * ( 1 - s * ( 1 - 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.0); + g = ((g1)*65535.0); + b = ((b1)*65535.0); + } + + // 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, 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::xyz2rgb (float x, float y, float z, float &r, float &g, float &b, 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, 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, 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; + + + float fcompl = 1.f; + if(complement) fcompl = 3.f; + // ponderate filters: report to R=G=B=33 + // I ponder RGB channel, not only orange or yellow or cyan, etc...it's my choice ! + if(mixerOrange != 33) { + if (mixerOrange >= 33) 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; + if(complement) obM =(-0.492f*mixerOrange+16.236f)/100.f; + mixerRed += orM; + mixerGreen += ogM; + mixerBlue += obM; + koymcp += (orM+ogM+obM); + } + if(mixerYellow != 33) { + yrM = fcompl*(-0.134f*mixerYellow+4.422f)/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(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; + if(complement) mgM =(-0.492f*mixerMagenta+16.236f)/100.f; + mixerRed += mrM; + mixerGreen += mgM; + mixerBlue += mbM; + koymcp += (mrM+mgM+mbM); + } + if(mixerPurple != 33) { + prM = fcompl*(-0.134f*mixerPurple+4.422f)/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) { + cgM = fcompl*(-0.134f*mixerCyan +4.422f)/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; + if (filter=="None") {filred=1.f; filgreen=1.f; filblue=1.f;} + else if (filter=="Red") {filred=1.f; filgreen=0.05f;filblue=0.f;} + else if (filter=="Orange") {filred=1.f; filgreen=0.6f; filblue=0.f;} + else if (filter=="Yellow") {filred=1.f; filgreen=1.f; filblue=0.05f;} + else if (filter=="YellowGreen") {filred=0.6f; filgreen=1.f; filblue=0.3f;} + else if (filter=="Green") {filred=0.2f; filgreen=1.f; filblue=0.3f;} + else if (filter=="Cyan") {filred=0.05f;filgreen=1.f; filblue=1.f;} + else if (filter=="Blue") {filred=0.f; filgreen=0.05f;filblue=1.f;} + else if (filter=="Purple") {filred=1.f; filgreen=0.05f;filblue=1.f;} + + + mixerRed = mixerRed * filred; + mixerGreen = mixerGreen * filgreen; + mixerBlue = mixerBlue * filblue; + + mixerRed = mixerRed / (mixerRed + mixerGreen + mixerBlue); + mixerGreen = mixerGreen / (mixerRed + mixerGreen + mixerBlue); + mixerBlue = mixerBlue / (mixerRed + mixerGreen + mixerBlue); + if(filter!="None") { + som = mixerRed+mixerGreen+mixerBlue; + if(setting=="RGB-Abs" || setting=="ROYGCBPM-Abs") kcorec = kcorec*som; + } + + } + + 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; + } + + 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[std::max(x,0.f)] : (327.68f*exp(log(x/MAXVALF)/3.0f ))); + fy = (y<65535.0f ? cachef[std::max(y,0.f)] : (327.68f*exp(log(y/MAXVALF)/3.0f ))); + fz = (z<65535.0f ? cachef[std::max(z,0.f)] : (327.68f*exp(log(z/MAXVALF)/3.0f ))); + + 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) ); + } + + double Color::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; + } + + /* + * 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 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::scalered ( float rstprotection, float param, float limit, float HH, float deltaHH, float &scale,float &scaleext) + { + if(rstprotection<99.9999) { + 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) + 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) + } + } + + void Color::transitred (float HH, float Chprov1, float dred, float factorskin, float protect_red, float factorskinext, float deltaHH, 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; + } + } + + /* + * 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; + float correctlumprov=0.0; + float correctlumprov2=0.0; + bool correctL=false; + 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(CC >= 6.0 && CC < 140) { //if C > 140 we say C=140 (only in Prophoto ...with very large saturation) + if (Chprov1 > 140) Chprov1=139; //limits of LUTf + if (Chprov1 < 6) Chprov1=6; + 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) { + 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, 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, 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.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: + * Labimage *lab : RT Lab data + * float *Lold : luminance before - data: i*width + j + * float *Cold : chrominance before - data: i*width + j + * bool corMuns : 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 + * Glib::ustring &working: working profile's name + * bool multiThread : parallelize the loop + */ + void Color::LabGamutMunsell(LabImage *lab, float *Lold, float *Cold, bool corMunsell, bool lumaMuns, bool isHLEnabled, bool gamut, const Glib::ustring &working, bool multiThread ) { +#ifdef _DEBUG + MyTime t1e,t2e; + t1e.set(); + int negat=0, moreRGB=0; + MunsellDebugInfo* MunsDebugInfo=NULL; + if (corMunsell) + MunsDebugInfo = new MunsellDebugInfo(); + + #pragma omp parallel default(shared) firstprivate(MunsDebugInfo) reduction(+: negat, moreRGB) if (multiThread) +#else + #pragma omp parallel default(shared) if (multiThread) +#endif + { + + //unsigned int N = lab->W*lab->H; + int width = lab->W, height = lab->H; + TMatrix wiprof = iccStore->workingSpaceInverseMatrix (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]} + }; + float correctlum=0.0; + float correctionHuechroma=0.0; + +#pragma omp for schedule(dynamic, 10) + for (int i=0; ib[i][j],lab->a[i][j]); + float Chprov1=sqrt(SQR(lab->a[i][j]/327.68f) + SQR(lab->b[i][j]/327.68f)); + float Lprov1=lab->L[i][j]/327.68f; + float Loldd, Coldd; + if(gamut) { +#ifdef _DEBUG + bool neg, more_rgb; +#endif + float R, G, B; + + //gamut control : Lab values are in gamut +#ifdef _DEBUG + gamutLchonly(HH, Lprov1, Chprov1, R, G, B, wip, isHLEnabled, 0.15f, 0.96f, neg, more_rgb); +#else + gamutLchonly(HH, Lprov1, Chprov1, R, G, B, wip, isHLEnabled, 0.15f, 0.96f); +#endif + +#ifdef _DEBUG + if(neg) negat++; + if(more_rgb) moreRGB++; +#endif + } + + Loldd = Lold[i*width + j]; + Coldd = Cold[i*width + j]; + lab->L[i][j] = Lprov1*327.68f; + correctionHuechroma = 0.0; + correctlum = 0.0; + + if(corMunsell) +#ifdef _DEBUG + AllMunsellLch(lumaMuns, Lprov1, Loldd, HH, Chprov1, Coldd, correctionHuechroma, correctlum, MunsDebugInfo); +#else + AllMunsellLch(lumaMuns, Lprov1, Loldd, HH, Chprov1, Coldd, correctionHuechroma, correctlum); +#endif + + HH+=correctlum; //hue Munsell luminance correction + + correctlum = 0.0f; + float2 sincosval = xsincosf(HH+correctionHuechroma); + lab->a[i][j] = Chprov1*sincosval.y*327.68f; + lab->b[i][j] = Chprov1*sincosval.x*327.68f; + + } + } // end of parallelization + +#ifdef _DEBUG + t2e.set(); + if (settings->verbose) { + 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, int chromx) { + + float reduction=0.3;// to be adapted...by tests + float extendedreduction=0.4; + float extendedreduction2=0.6; + + if(chromx==1) {reduction=0.6;extendedreduction=0.7;extendedreduction2=0.8;} + + float C9=0.0, C8=0.0, C7=0.0, C4=0.0, C3=0.0, C2=0.0, C1=0.0; + float H9=0.0, H8=0.0, H7=0.0, H4=0.0, H3=0.0, H2=0.0, H1=0.0, H10=0.0,H11=0.0; + 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 ?? + C9=8.0;C8=15.0;C7=12.0;C4=7.0;C3=5.0;C2=5.0;C1=5.0; + + // wide area for transition + + if (lum >= 92.0 && (hue > -0.1 && hue < 1.65) && (chrom > 7.0 && chrom < (18.0))) satreduc=extendedreduction2; + else if (lum >= 85.0 && lum < 92.0 && (hue > 0.0 && hue < 1.65) && (chrom > 7.0 && chrom < (35.0+C9))) satreduc=extendedreduction2; + else if ((lum > 20 && lum < 85) && (hue > (0.02 + H11) && hue < 1.65) && (chrom > 7.0 && chrom < (55.0+C9) )) satreduc=extendedreduction2; + else if (lum < 20.0 && (hue > (0.02+H11) && hue < 1.60) && (chrom > 7.0 && chrom < (45.0+C1) )) satreduc=extendedreduction2; + + // wide area skin color, useful if not accurate colorimetry or if the user has changed hue and saturation + + if (lum >= 92.0 && (hue > 0.8 && hue < 1.65) && (chrom > 7.0 && chrom < (15.0))) satreduc=extendedreduction; + else if (lum >= 85.0 && lum < 92.0 && (hue > 0.70 && hue < 1.4) && (chrom > 7.0 && chrom < (26.0+C9))) satreduc=extendedreduction; + else if ((lum > 20 && lum < 85) && (hue > (0.02 + H11) && hue < 1.5) && (chrom > 7.0 && chrom < (48.0+C9) )) satreduc=extendedreduction; + else if (lum < 20.0 && (hue > (0.02+H11) && hue < 1.0) && (chrom > 7.0 && chrom < (35.0+C1) )) satreduc=extendedreduction; + + // "real" skin color : take into account a slightly usage of contrast and saturation in RT if option "skin" = 1 + + if (lum >= 85.0 && (hue > (0.78-H9) && hue < (1.18+H9)) && (chrom > 8.0 && chrom < (14.0+C9))) satreduc=reduction; + else if ((lum >= 70.0 && lum < 85.0) && (hue > 0.4 && hue < (1.04+H8)) && (chrom > 8.0 && chrom < (35.0+C8))) satreduc=reduction; + else if ((lum >= 52.0 && lum < 70.0) && (hue > 0.3 && hue < (1.27+H7)) && (chrom > 11.0 && chrom < (35.0+C7))) satreduc=reduction; + else if ((lum >= 35.0 && lum < 52.0) && (hue > 0.3 && hue < (1.25+H4)) && (chrom > 13.0 && chrom < (37.0+C4))) satreduc=reduction; + else if ((lum >= 20.0 && lum < 35.0) && (hue > 0.3 && hue < (1.20+H3)) && (chrom > 7.0 && chrom <(35.0+C3) )) satreduc=reduction; + else if ((lum > 10.0 && lum < 20.0) && (hue > (0.0 + H10) && hue < (0.95 +H2)) && (chrom > 8.0 && chrom < (23.0+C2))) satreduc=reduction; + else if ((lum < 10.0) && (hue > (0.02 + H10) && hue < (0.90+H1)) && (chrom > 8.0 && chrom < (23.0+C1))) satreduc=reduction; // no data : extrapolate + } + + /* + * 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); + 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); + 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); + 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); + 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); + for (int i=0; i5) _5B80[i] = -2.45 +0.003*(i-5); + } + //printf("5B %1.2f\n",_5B80[49]); + + _7B40(maxInd2); + 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); + 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); + 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); + 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); + for (int i=0; i5) _7B80[i] = -2.30 +0.0028*(i-5); + } + //printf("5B %1.2f\n",_7B80[49]); + + _9B40(maxInd2); + 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); + 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); + 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); + 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); + for (int i=0; i5) _9B80[i] = -2.16 +0.0025*(i-5); + } + //printf("9B %1.2f\n",_9B80[49]); + + _10B40(maxInd2); + 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); + 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); + 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); + for (int i=0; i5) _10B70[i] = -2.03 +0.0025*(i-5); + } + //printf("10B %1.2f\n",_10B70[49]); + _10B80(maxInd3); + for (int i=0; i5) _10B80[i] = -2.08 +0.0032*(i-5); + } + //printf("10B %1.2f\n",_10B80[39]); + + _05PB40(maxInd2); + 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); + 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); + 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); + 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); + 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); + for (int i=0; i5) _15PB10[i] = -1.66 +0.0035*(i-5); + } + //printf("15 %1.2f\n",_15PB10[49]); + _15PB20(maxInd2); + 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); + 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); + 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); + 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); + 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); + for (int i=0; i5) _15PB70[i] = -1.90 +0.0027*(i-5); + } + // printf("15 %1.2f\n",_15PB70[49]); + _15PB80(maxInd3); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + for (int i=0; i5) _3PB70[i] = -1.76 +0.002*(i-5); + } + //printf("30 %1.2f\n",_3PB70[49]); + _3PB80(maxInd3); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + for (int i=0; i5) _45PB70[i] = -1.63 +0.0017*(i-5); + } + //printf("45 %1.2f\n",_45PB70[49]); + _45PB80(maxInd3); + 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); + 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); + 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); + 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); + 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 + 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 + 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); + for (int i=0; i5) _6PB70[i] = -1.49 +0.0018*(i-5); + } + //printf("6 %1.2f\n",_6PB70[49]); + _6PB80(maxInd3); + 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 + 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 + 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 + 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 + 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 + 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); + 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); + for (int i=0; i5) _75PB70[i] = -1.34 +0.002*(i-5); + } + _75PB80(maxInd3); + for (int i=0; i5) _75PB80[i] = -1.35 +0.00125*(i-5); + } + + + _9PB10(maxInd); + 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); + 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); + 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); + 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); + 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); + 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); + for (int i=0; i5) _9PB70[i] = -1.23 +0.0018*(i-5); + } + //printf("9 %1.2f\n",_9PB70[49]); + _9PB80(maxInd3); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + for (int i=0; i5) _85YR20[i] = 1.12 +0.004*(i-5); + } + + //printf("85YR %1.2f \n",_85YR20[44]); + _85YR30(maxInd2); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + for (int i=0; i5) _7YR80[i] = 1.29 - 0.0008*(i-5); + } + //printf("7YR %1.2f \n",_7YR80[44] ); + _55YR30(maxInd3); + for (int i=0; i5) _55YR30[i] = 0.96 + 0.0038*(i-5); + } + //printf("55YR %1.2f \n",_55YR30[44] ); + _55YR40(maxInd2); + 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); + 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); + 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); + 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); + 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); + for (int i=0; i5) _55YR90[i] = 1.19 - 0.0005*(i-5); + } + //printf("55YR %1.2f \n",_55YR90[44] ); + + _4YR30(maxInd2); + 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); + 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); + 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); + 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); + 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); + for (int i=0; i5) _4YR80[i] = 1.09 - 0.0002*(i-5); + } + //printf("4YR %1.2f \n",_4YR80[41] ); + + _25YR30(maxInd2); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + for (int i=0; i5) _25R10[i] = -0.03 - 0.002*(i-5); + } + //printf("25R %1.2f \n",_25R10[44]); + _25R20(maxInd2); + 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); + 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); + for (int i=0; i5) _10RP10[i] = -0.16 - 0.0017*(i-5); + } + //printf("10RP %1.2f \n",_10RP10[44]); + _10RP20(maxInd2); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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..15cf6f72b --- /dev/null +++ b/rtengine/color.h @@ -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 . + */ + +#ifndef _COLOR_H_ +#define _COLOR_H_ + +#include "rt_math.h" +#include "LUT.h" +#include "labimage.h" +#include "iccstore.h" +#include "iccmatrices.h" + +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: + const static double sRGBGamma; // standard average gamma + const static double sRGBGammaCurve; // 2.4 in the curve + const static double 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_26_11; + static LUTf gammatab_26_11; + static LUTf igammatab_24_17; + static LUTf gammatab_24_17a; + + // look-up tables for the simple exponential gamma + static LUTf gammatab; + + + static void init (); + static void cleanup (); + + static float rgbLuminance(float r, float g, float b) { return r*float(xyz_sRGBd65[1][0]) + g*float(xyz_sRGBd65[1][1]) + b*float(xyz_sRGBd65[1][2]); } + static double rgbLuminance(double r, double g, double b) { return r*xyz_sRGBd65[1][0] + g*xyz_sRGBd65[1][1] + b*xyz_sRGBd65[1][2]; } + static void rgb2hsl (float r, float g, float b, float &h, float &s, float &l); + static void hsl2rgb (float h, float s, float l, float &r, float &g, float &b); + static void rgb2hsv (float r, float g, float b, float &h, float &s, float &v); + 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); + static void hsv2rgb01 (float h, float s, float v, float &r, float &g, float &b); + static void xyz2srgb (float x, float y, float z, float &r, float &g, float &b); + static void xyz2Prophoto (float x, float y, float z, float &r, float &g, float &b); + static void Prophotoxyz (float r, float g, float b, float &x, float &y, float &z); + static void xyz2rgb (float x, float y, float z, float &r, float &g, float &b, double rgb_xyz[3][3]); + static void xyz2rgb (float x, float y, float z, float &r, float &g, float &b, float rgb_xyz[3][3]); + static void rgbxyz (float r, float g, float b, float &x, float &y, float &z, double xyz_rgb[3][3]); + + static void Lab2XYZ(float L, float a, float b, float &x, float &y, float &z); + static void XYZ2Lab(float X, float Y, float Z, float &L, float &a, float &b); + static void Lab2Yuv(float L, float a, float b, float &Y, float &u, float &v); + static void Yuv2Lab(float Y, float u, float v, float &L, float &a, float &b, double wp[3][3]); + static double f2xyz(double f); + static void calcGamma (double pwr, double ts, int mode, int imax, double &gamma0, double &gamma1, double &gamma2, double &gamma3, double &gamma4,double &gamma5); + static void trcGammaBW (float &r, float &g, float &b, float gammabwr, float gammabwg, float gammabwb); + static void computeBWMixerConstants (const Glib::ustring &setting, const Glib::ustring &filter, 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 + static inline double gamma2 (double x) { + return x <= 0.003041 ? x*12.92 : 1.055011*exp(log(x)/sRGBGammaCurve)-0.055011; + } + static inline double igamma2 (double x) { + return x <= 0.039293 ? x/12.92 : exp(log((x+0.055011)/1.055011)*sRGBGammaCurve); + } +/* static inline double gamma709 (double x) { + return x <= 0.0176 ? x*4.5 : 1.0954*exp(log(x)/2.2)-0.0954; + } + static inline double igamma709 (double x) { + return x <= 0.0795 ? x/4.5 : exp(log((x+0.0954)/1.0954)*2.2); + } +*/ + static inline double gamma24_17 (double x) { + return x <= 0.001867 ? x*17.0 : 1.044445*exp(log(x)/2.4)-0.044445; + } + static inline double igamma24_17 (double x) { + return x <= 0.031746 ? x/17.0 : exp(log((x+0.044445)/1.044445)*2.4); + } + + static inline double gamma26_11 (double x) { + return x <= 0.004921 ? x*11.0 : 1.086603*exp(log(x)/2.6)-0.086603; + } + static inline double igamma26_11 (double x) { + return x <= 0.054127 ? x/11.0 : exp(log((x+0.086603)/1.086603)*2.6); + } + + // 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 double gamman (double x, double gamma){//gamma standard without slope... + return (x =exp(log(x)/gamma)); + } + static inline double igamman (double x, double gamma){//inverse gamma standard without slope... + return (x = exp(log(x)*gamma) ); + } + + // gamma functions on [0,65535] based on look-up tables + 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 +#ifdef _DEBUG + static void AllMunsellLch (bool lumaMuns, float Lprov1, float Loldd, float HH, float Chprov1, float CC, float &correctionHueChroma, float &correctlum, MunsellDebugInfo* munsDbgInfo); + static void gamutLchonly (float HH, float &Lprov1, float &Chprov1, float &R, float &G, float &B, double wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef, bool &neg, bool &more_rgb); +#else + static void AllMunsellLch (bool lumaMuns, float Lprov1, float Loldd, float HH, float Chprov1, float CC, float &correctionHueChroma, float &correctlum); + static void gamutLchonly (float HH, float &Lprov1, float &Chprov1, float &R, float &G, float &B, double wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef); +#endif + static void LabGamutMunsell (LabImage *lab, float *Lold, float *Cold, bool corMunsell, bool lumaMuns, bool isHLEnabled, bool gamut, const Glib::ustring &working, bool multiThread ); + + static void SkinSat (float lum, float hue, float chrom, float &satreduc, int chromx);//jacques Skin color + 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 ( float rstprotection, float param, float limit, float HH, float deltaHH, float &scale, float &scaleext); + static void transitred (float HH, float Chprov1, float dred, float factorskin, float protect_red, float factorskinext, float deltaHH, float factorsat, float &factor); + static void skinred ( double J, double h, double sres, double Sp, float dred, float protect_red, int sk, float rstprotection, float ko, double &s); + static void skinredfloat ( float J, float h, float sres, float Sp, float dred, float protect_red, int sk, float rstprotection, float ko, float &s); + + //void gamutmap(LabImage* ); + static void gamutmap(float &X, float &Y, float &Z, const double p[3][3]); + + 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; + //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. full red + else if (HH>=0.6f && HH < 1.4f) hr=0.1125*double(HH) - 0.0675; //hr 0.0 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.5 green + else if (HH>=-2.8f && HH < -2.3f) hr=0.16*double(HH) + 0.948; //hr 0.5 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); + } + + + static inline float f2xyz(float f) { + const float epsilonExpInv3 = 6.0/29.0; + const float kappaInv = 27.0/24389.0; // inverse of kappa + + return (f > epsilonExpInv3) ? f*f*f : (116 * f - 16) * kappaInv; + } + +}; + +} + +#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..d5b89b0f8 --- /dev/null +++ b/rtengine/colortemp.cc @@ -0,0 +1,2440 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 "iccmatrices.h" +#include "rtengine.h" +#include "improcfun.h" +#include "curves.h" +#include +#include +#include +#include "mytime.h" +#include "sleef.c" +#include "../rtgui/options.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 { + using namespace procparams; + + 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::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 ColorTemp::curvecolorfloat(float satind, float satval, float &sres, float parsat) { + if (satind >=0.0f) { + sres = (1.-(satind)/100.f)*satval+(satind)/100.f*(1.f-SQR(SQR(1.f-min(satval,1.0f)))); + if (sres>parsat) sres=parsat; + if (sres<0.f) sres=0.f; + } else { + if (satind < -0.1f) + sres = satval*(1.f+(satind)/100.f); + } +} + + +void ColorTemp::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 ColorTemp::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]; +} + +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, Glib::ustring 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 <= 4000) { + // 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(0., 0., 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, 0., 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=true; + // 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 <= 4000) { + // 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(0., 0., 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, 0., 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<4000) { + 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; + } + //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)); + } + } + } +} +/* J.Desmis october 2012 - CIECAM02 : +I have notably modified the code of Billy Biggs to adapt to RT +The code is update from last works of M.Fairchild +and also gamut correction M.H.Brill S.Susstrunk +*/ + +/** + * 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. + * + */ +void ColorTemp::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 ColorTemp::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); + +} +} + + + void ColorTemp::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); + +} +} + + void ColorTemp::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); + +} +} + + +void ColorTemp::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; + +} + + void ColorTemp::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; + +} + + + +void ColorTemp::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 ColorTemp::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); + } +} + + + void ColorTemp::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); +} + void ColorTemp::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); +} + +void ColorTemp::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; + } +} +void ColorTemp::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 = 21.0f/20.0f; + if( fabs( sinh ) >= fabs( cosh ) ) { + bb = ((0.32787f * x) * (2.0f + p3)) / + ((e / (t * sinh)) - + // ((0.32145 - 0.63507 - (p3 * 0.15681)) * (cosh / sinh)) - + // (0.20527 - 0.18603 - (p3 * 4.49038))); + ((-0.31362f - (p3 * 0.15681f)) * (cosh / sinh)) - + (0.01924f - (p3 * 4.49038f))); + + aa = (bb * cosh) / sinh; + } else { + aa = ((0.32787f * x) * (2.0f + p3)) / + ((e / (t * cosh)) - + // (0.32145 - 0.63507 - (p3 * 0.15681)) - + // ((0.20527 - 0.18603 - (p3 * 4.49038)) * (sinh / cosh))); + (-0.31362f - (p3 * 0.15681f)) - + ((0.01924f - (p3 * 4.49038f)) * (sinh / cosh))); + + bb = (aa * sinh) / cosh; + } +} + + +void ColorTemp::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 ColorTemp::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 ColorTemp::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 ColorTemp::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 ColorTemp::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, myj, myc, myq, mym, mys; + 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)); + + ColorTemp::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 ColorTemp::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) + + { + 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, myj, myc, myq, mym, mys; + 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)); + + ColorTemp::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) / 11.0f) + (bpa / 11.0f); + cb = (1.0f / 9.0f) * (rpa + gpa - (2.0f * bpa)); + + myh = (180.0f / M_PI) * xatan2f( cb, ca ); + if( myh < 0.0f ) myh += 360.0f; + //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.0f * rpa) + gpa + ((1.0f / 20.0f) * bpa) - 0.305f) * nbb; + if (gamu==1) a=MAXR(a,0.0f);//gamut correction M.H.Brill S.Susstrunk + J = 100.0f * pow_F( a / aw, c * cz ); + + e = ((12500.0f / 13.0f) * nc * ncb) * (xcosf( ((myh * M_PI) / 180.0f) + 2.0f ) + 3.8f); + t = (e * sqrt( (ca * ca) + (cb * cb) )) / (rpa + gpa + ((21.0f / 20.0f) * bpa)); + + C = pow_F( t, 0.9f ) * sqrt( J / 100.0f ) + * pow_F( 1.64f - pow_F( 0.29f, n ), 0.73f ); + + Q = wh * sqrt( J / 100.0f ); + M = C * pfl; + s = 100.0f * sqrt( M / Q ); + h = myh; + +} + + +void ColorTemp::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; + ColorTemp::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 ); + + ColorTemp::hpe_to_xyz( x, y, z, rp, gp, bp ); + ColorTemp::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)); + + ColorTemp::cat02_to_xyz( x, y, z, r, g, b, gamu ); +} + +void ColorTemp::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) + +{ + 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; + ColorTemp::xyz_to_cat02float( rw, gw, bw, xw, yw, zw, gamu ); + e = ((12500.0f / 13.0f) * 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( C / (sqrt( J / 100.f) * pow_F( 1.64f - pow_F( 0.29f, n ), 0.73f )), 10.0f / 9.0f ); + + 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 ); + + ColorTemp::hpe_to_xyzfloat( x, y, z, rp, gp, bp ); + ColorTemp::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)); + + ColorTemp::cat02_to_xyzfloat( x, y, z, r, g, b, gamu ); +} + + +//end CIECAM Billy Bigg + + + + + +/* + Calculate Planck's radiation +*/ + //calculate spectral data for blackbody at temp! +double ColorTemp::blackbody_spect(double wavelength, double m1, double m2, double temp) +{ + double wlm = wavelength * 1e-9; /* Wavelength in meters */ + return (3.7417715247e-16 * pow(wlm, -5.0)) / //3.7417..= c1 = 2*Pi*h*c2 where h=Planck constant, c=velocity of light + (exp(1.438786e-2 / (wlm * temp)) - 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 _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 = daylight_spect(lambda, _m1, _m2, _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_blackbody(double _m1, double _m2, 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, _m1, _m2, _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 _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 = daylight_spect(lambda,_m1, _m2, _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 = daylight_spect(lambda,_m1, _m2, _temp); + 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 _m1, double _m2, 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,_m1, _m2, _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,_m1, _m2, _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, double temp) +{ + //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..45ff7a7b1 --- /dev/null +++ b/rtengine/colortemp.h @@ -0,0 +1,355 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 "procparams.h" + +#include +#include +#include "sleef.c" +#include "LUT.h" +#define MAXR(a,b) ((a) > (b) ? (a) : (b)) +#define pow_F(a,b) (xexpf(b*xlogf(a))) + + +namespace rtengine { +using namespace procparams; + + +#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; + Glib::ustring 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 Glib::ustring 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, Glib::ustring 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); + + static double d_factor( double f, double la ) { + return f * (1.0 - ((1.0 / 3.6) * exp((-la - 42.0) / 92.0))); + } + static float d_factorfloat( float f, float la ) { + return f * (1.0f - ((1.0f / 3.6f) * xexpf((-la - 42.0f) / 92.0f))); + } + + static double 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)); + } + static float 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)); + } + + static double 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; + } + + static float 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; + } + + 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 ); + static void cat02_to_xyzfloat ( float &x, float &y, float &z, float r, float g, float b, int gamu ); + static void hpe_to_xyzfloat ( float &x, float &y, float &z, float r, float g, float b ); + + static void Aab_to_rgb( double &r, double &g, double &b, double A, double aa, double bb, double nbb ); + static void Aab_to_rgbfloat( float &r, float &g, float &b, float A, float aa, float bb, float nbb ); + static void calculate_ab( double &aa, double &bb, double h, double e, double t, double nbb, double a ); + static void calculate_abfloat( float &aa, float &bb, float h, float e, float t, float nbb, float a ); + + + static double 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;} + } + static float 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;} + } + + static double 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 ); + } + static float inverse_nonlinear_adaptationfloat( float c, float fl ) { + int c1; + if(c-0.1f < 0.0f) c1=-1; else c1=1; + return c1*(100.0f / fl) * pow_F( (27.13f * fabs( c - 0.1f )) / (400.0f - fabs( c - 0.1f )), 1.0f / 0.42f ); + } + + + 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 ) ; + + 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 m1, double m2, double temp); + static double daylight_spect (double wavelength, double m1, double m2, double temp); + 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 _temp, double &x, double &y, double &z); + static void spectrum_to_xyz_blackbody (double _m1, double _m2, 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 _temp, double &xx, double &yy, double &zz); + static void spectrum_to_color_xyz_blackbody (const double* spec_color, double _m1, double _m2, 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); + + + +/** + * 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); + + 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 ); + +/** + * 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 ); + + +}; +} +#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..27b885827 --- /dev/null +++ b/rtengine/cplx_wavelet_dec.cc @@ -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 . + * + * 2010 Ilya Popov + * 2012 Emil Martinec + */ + +#include "cplx_wavelet_dec.h" + +namespace rtengine { + + cplx_wavelet_decomposition::~cplx_wavelet_decomposition() + { + for(int i = 0; i <= lvltot; i++) { + for (int j=0; j<4; j++) { + delete dual_tree[i][j]; + } + } + delete[] first_lev_anal; + delete[] first_lev_synth; + delete[] wavfilt_anal; + delete[] wavfilt_synth; + } + + wavelet_decomposition::~wavelet_decomposition() + { + for(int i = 0; i <= lvltot; i++) { + delete wavelet_decomp[i]; + } + delete[] wavfilt_anal; + delete[] wavfilt_synth; + } + +}; + diff --git a/rtengine/cplx_wavelet_dec.h b/rtengine/cplx_wavelet_dec.h new file mode 100644 index 000000000..de0b0b966 --- /dev/null +++ b/rtengine/cplx_wavelet_dec.h @@ -0,0 +1,455 @@ +/* + * 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 { + + +// %%%%%%%%%%%%%%%%%%%%%%%%%%% + +template +void copy_out(A * a, A * b, size_t datalen) +{// for standard wavelet decomposition + memcpy(b, a, datalen*sizeof(A)); +} + +template +void copy_out(A ** a, B * b, size_t datalen) +{// for complex wavelet decomposition + for (size_t j=0; j (0.25*(a[0][j]+a[1][j]+a[2][j]+a[3][j])); + } +} + +template +void copy_out(A * a, B * b, size_t datalen) +{// for standard wavelet decomposition + for (size_t j=0; j (a[j]); + } +} + +// %%%%%%%%%%%%%%%%%%%%%%%%%%% + + +class cplx_wavelet_decomposition +{ +public: + + typedef float internal_type; + +private: + + // static const int maxlevels = 8;//should be greater than any conceivable order of decimation + static const int maxlevels = 9;//should be greater than any conceivable order of decimation + + int lvltot, subsamp; + size_t m_w, m_h;//dimensions + + int first_lev_len, first_lev_offset; + float *first_lev_anal; + float *first_lev_synth; + + int wavfilt_len, wavfilt_offset; + float *wavfilt_anal; + float *wavfilt_synth; + + int testfilt_len, testfilt_offset; + float *testfilt_anal; + float *testfilt_synth; + + wavelet_level * dual_tree[maxlevels][4]; + +public: + + template + cplx_wavelet_decomposition(E * src, int width, int height, int maxlvl, int subsampling); + + ~cplx_wavelet_decomposition(); + + internal_type ** level_coeffs(int level, int branch) const + { + return dual_tree[level][branch]->subbands(); + } + + int level_W(int level, int branch) const + { + return dual_tree[level][branch]->width(); + } + + int level_H(int level, int branch) const + { + return dual_tree[level][branch]->height(); + } + + int level_pad(int level, int branch) const + { + return dual_tree[level][branch]->padding(); + } + + int maxlevel() const + { + return lvltot; + } + + template + void reconstruct(E * dst); + +}; + + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + template + cplx_wavelet_decomposition::cplx_wavelet_decomposition(E * src, int width, int height, int maxlvl, int subsampling) + : lvltot(0), subsamp(subsampling), m_w(width), m_h(height) + { + + //initialize wavelet filters + + first_lev_len = FSFarras_len; + first_lev_offset = FSFarras_offset; + first_lev_anal = new float[4*first_lev_len]; + first_lev_synth = new float[4*first_lev_len]; + + for (int n=0; n<2; n++) { + for (int m=0; m<2; m++) { + for (int i=0; i(src, lvltot, subsamp, padding, m_w, m_h, first_lev_anal+first_lev_len*2*n, \ + first_lev_anal+first_lev_len*2*m, first_lev_len, first_lev_offset); + while(lvltot < maxlvl) { + lvltot++; + dual_tree[lvltot][2*n+m] = new wavelet_level(dual_tree[lvltot-1][2*n+m]->lopass()/*lopass*/, lvltot, subsamp, 0/*no padding*/, \ + dual_tree[lvltot-1][2*n+m]->width(), \ + dual_tree[lvltot-1][2*n+m]->height(), \ + wavfilt_anal+wavfilt_len*2*n, wavfilt_anal+wavfilt_len*2*m, \ + wavfilt_len, wavfilt_offset); + } + } + } + + + //rotate detail coefficients + float coeffave[5][4][3]; + + float root2 = sqrt(2); + for (int lvl=0; lvlwidth(); + int Hlvl = dual_tree[lvl][0]->height(); + for (int n=0; n<4; n++) + for (int m=1; m<4; m++) + coeffave[lvl][n][m-1]=0; + + for (int m=1; m<4; m++) {//detail coefficients only + for (int i=0; iwavcoeffs[m][i] + dual_tree[lvl][3]->wavcoeffs[m][i])/root2; + dual_tree[lvl][3]->wavcoeffs[m][i] = (dual_tree[lvl][0]->wavcoeffs[m][i] - dual_tree[lvl][3]->wavcoeffs[m][i])/root2; + dual_tree[lvl][0]->wavcoeffs[m][i] = wavtmp; + + wavtmp = (dual_tree[lvl][1]->wavcoeffs[m][i] + dual_tree[lvl][2]->wavcoeffs[m][i])/root2; + dual_tree[lvl][2]->wavcoeffs[m][i] = (dual_tree[lvl][1]->wavcoeffs[m][i] - dual_tree[lvl][2]->wavcoeffs[m][i])/root2; + dual_tree[lvl][1]->wavcoeffs[m][i] = wavtmp; + + for (int n=0; n<4; n++) coeffave[lvl][n][m-1] += fabs(dual_tree[lvl][n]->wavcoeffs[m][i]); + } + } + for (int n=0; n<4; n++) + for (int i=0; i<3; i++) + coeffave[lvl][n][i] /= Wlvl*Hlvl; + } + + } + + /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */ + + + template + void cplx_wavelet_decomposition::reconstruct(E * dst) { + + // data structure is wavcoeffs[scale][2*n+m=2*(Re/Im)+dir][channel={lo,hi1,hi2,hi3}][pixel_array] + + //rotate detail coefficients + float root2 = sqrt(2); + for (int lvl=0; lvlwidth(); + int Hlvl = dual_tree[lvl][0]->height(); + for (int i=0; iwavcoeffs[m][i] + dual_tree[lvl][3]->wavcoeffs[m][i])/root2; + dual_tree[lvl][3]->wavcoeffs[m][i] = (dual_tree[lvl][0]->wavcoeffs[m][i] - dual_tree[lvl][3]->wavcoeffs[m][i])/root2; + dual_tree[lvl][0]->wavcoeffs[m][i] = wavtmp; + + wavtmp = (dual_tree[lvl][1]->wavcoeffs[m][i] + dual_tree[lvl][2]->wavcoeffs[m][i])/root2; + dual_tree[lvl][2]->wavcoeffs[m][i] = (dual_tree[lvl][1]->wavcoeffs[m][i] - dual_tree[lvl][2]->wavcoeffs[m][i])/root2; + dual_tree[lvl][1]->wavcoeffs[m][i] = wavtmp; + } + } + } + + internal_type ** tmp = new internal_type *[4]; + for (int i=0; i<4; i++) { + tmp[i] = new internal_type[m_w*m_h]; + } + + for (int n=0; n<2; n++) { + for (int m=0; m<2; m++) { + int skip=1<<(lvltot-1); + for (int lvl=lvltot-1; lvl>0; lvl--) { + dual_tree[lvl][2*n+m]->reconstruct_level(dual_tree[lvl-1][2*n+m]->wavcoeffs[0], wavfilt_synth+wavfilt_len*2*n, \ + wavfilt_synth+wavfilt_len*2*m, wavfilt_len, wavfilt_offset); + skip /=2; + } + dual_tree[0][2*n+m]->reconstruct_level(tmp[2*n+m], first_lev_synth+first_lev_len*2*n, + first_lev_synth+first_lev_len*2*m, first_lev_len, first_lev_offset); + } + } + + copy_out(tmp,dst,m_w*m_h); + + for (int i=0; i<4; i++) { + delete[] tmp[i]; + } + delete[] tmp; + + + + } + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + class wavelet_decomposition + { + public: + + typedef float internal_type; + + private: + + static const int maxlevels = 9;//should be greater than any conceivable order of decimation + + int lvltot, subsamp; + size_t m_w, m_h;//dimensions + + int wavfilt_len, wavfilt_offset; + float *wavfilt_anal; + float *wavfilt_synth; + + int testfilt_len, testfilt_offset; + float *testfilt_anal; + float *testfilt_synth; + + wavelet_level * wavelet_decomp[maxlevels]; + + public: + + template + wavelet_decomposition(E * src, int width, int height, int maxlvl, int subsampling); + + ~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_pad(int level) const + { + return wavelet_decomp[level]->padding(); + } + + int level_stride(int level) const + { + return wavelet_decomp[level]->stride(); + } + + int maxlevel() const + { + return lvltot; + } + + int subsample() const + { + return subsamp; + } + + template + void reconstruct(E * dst); + + }; + + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + template + wavelet_decomposition::wavelet_decomposition(E * src, int width, int height, int maxlvl, int subsampling) + : lvltot(0), subsamp(subsampling), m_w(width), m_h(height) + { + + //initialize wavelet filters + + wavfilt_len = Daub4_len; + wavfilt_offset = Daub4_offset; + wavfilt_anal = new float[2*wavfilt_len]; + wavfilt_synth = new float[2*wavfilt_len]; + + for (int n=0; n<2; n++) { + for (int i=0; i(src, lvltot/*level*/, subsamp, padding/*padding*/, m_w, m_h, \ + wavfilt_anal, wavfilt_anal, wavfilt_len, wavfilt_offset); + while(lvltot < maxlvl) { + lvltot++; + wavelet_decomp[lvltot] = new wavelet_level(wavelet_decomp[lvltot-1]->lopass()/*lopass*/, lvltot/*level*/, subsamp, 0/*no padding*/, \ + wavelet_decomp[lvltot-1]->width(), wavelet_decomp[lvltot-1]->height(), \ + wavfilt_anal, wavfilt_anal, wavfilt_len, wavfilt_offset); + } + + + } + + /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */ + /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */ + + + template + void wavelet_decomposition::reconstruct(E * dst) { + + // data structure is wavcoeffs[scale][channel={lo,hi1,hi2,hi3}][pixel_array] + + //int skip=1<<(lvltot-1); + for (int lvl=lvltot-1; lvl>0; lvl--) { + wavelet_decomp[lvl]->reconstruct_level(wavelet_decomp[lvl-1]->wavcoeffs[0], wavfilt_synth, wavfilt_synth, wavfilt_len, wavfilt_offset); + //skip /=2; + } + + internal_type * tmp = new internal_type[m_w*m_h]; + + wavelet_decomp[0]->reconstruct_level(tmp, wavfilt_synth, wavfilt_synth, wavfilt_len, wavfilt_offset); + + copy_out(tmp,dst,m_w*m_h); + + delete[] tmp; + + + + } + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + +}; + +#endif diff --git a/rtengine/cplx_wavelet_filter_coeffs.h b/rtengine/cplx_wavelet_filter_coeffs.h new file mode 100644 index 000000000..ac537d0a1 --- /dev/null +++ b/rtengine/cplx_wavelet_filter_coeffs.h @@ -0,0 +1,129 @@ +/* + * 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 + */ + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +//#include "improcfun.h" + +#ifdef _OPENMP +#include +#endif + + +namespace rtengine { + + +// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +/*const int AntonB_len = 12;//length of filter +const int AntonB_offset = 6;//offset + +const float AntonB_anal[2][2][12] = {//analysis filter + {{0, -0.08838834764832, 0.08838834764832, 0.69587998903400, 0.69587998903400, + 0.08838834764832, -0.08838834764832, 0.01122679215254, 0.01122679215254, 0}, + {0, 0, 0, 0.04563588155712, -0.02877176311425, -0.29563588155712 , + 0.55754352622850, -0.29563588155713, -0.02877176311425, 0.04563588155712, 0, 0}}, + {{0 , 0 , 0.02674875741081, -0.01686411844287, -0.07822326652899, 0.26686411844288, + 0.60294901823636, 0.26686411844287, -0.07822326652899, -0.01686411844287, 0.02674875741081, 0}, + {0 , 0 , 0, 0 , 0.04563588155712, -0.02877176311425, + -0.29563588155712 , 0.55754352622850, -0.29563588155713, -0.02877176311425, 0.04563588155712 , 0}} }; + +const float AntonB_synth[2][2][12] = {//synthesis filter + {{0 , 0 , 0, -0.04563588155712, -0.02877176311425, 0.29563588155712, + 0.55754352622850, 0.29563588155713, -0.02877176311425, -0.04563588155712, 0, 0}, + {0, 0.02674875741081, 0.01686411844287, -0.07822326652899, -0.26686411844288 , 0.60294901823636, + -0.26686411844287, -0.07822326652899, 0.01686411844287, 0.02674875741081, 0, 0}}, + {{0 , 0, -0.04563588155712, -0.02877176311425, 0.29563588155712 , 0.55754352622850 , + 0.29563588155713, -0.02877176311425, -0.04563588155712, 0, 0 , 0}, + {0.02674875741081 , 0.01686411844287, -0.07822326652899, -0.26686411844288 , 0.60294901823636, -0.26686411844287, + -0.07822326652899, 0.01686411844287 , 0.02674875741081 , 0 , 0, 0}} };*/ + + +/* for (int i=0; i<4; i++) + for (int n=0; n<12; n++) { + AntonB.synth[i][n] *= 2; + }*/ + +// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +const int FSFarras_len=10;//length of filter +const int FSFarras_offset=4;//offset + +const float FSFarras_anal[2][2][10] = {//analysis filter + {{0, -0.08838834764832, 0.08838834764832, 0.69587998903400, 0.69587998903400, 0.08838834764832, -0.08838834764832, 0.01122679215254 , 0.01122679215254, 0}, + { 0, -0.01122679215254, 0.01122679215254, 0.08838834764832, 0.08838834764832, -0.69587998903400, 0.69587998903400, -0.08838834764832, -0.08838834764832, 0}}, + {{0.01122679215254, 0.01122679215254, -0.08838834764832, 0.08838834764832, 0.69587998903400, 0.69587998903400, 0.08838834764832, -0.08838834764832, 0, 0}, + {0, 0, -0.08838834764832, -0.08838834764832, 0.69587998903400, -0.69587998903400, 0.08838834764832, 0.08838834764832, 0.01122679215254, -0.01122679215254}} }; + +//synthesis filter is the reverse (see cplx_wavelet_dec.h) + + +// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +/* + % Kingsbury Q-filters for the dual-tree complex DWT + % + % af{i},i=1,2-analysis filters for tree i + % sf{i},i=1,2-synthesis filters for tree i + % note:af{2} is the reverse of af{1} + % ordering is {af[1],af[2],sf[1],sf[2]} + % REFERENCE:% N.G.Kingsbury,"A dual-tree complex wavelet + % transform with improved orthogonality and symmetry + % properties",Proceedings of the IEEE Int.Conf.on + % Image Proc.(ICIP),2000 */ + +const int Kingsbury_len=10;//length of filter +const int Kingsbury_offset=4;//offset + +const float Kingsbury_anal[2][2][10] = {//analysis filter + {{0.03516384000000, 0, -0.08832942000000, 0.23389032000000, 0.76027237000000, 0.58751830000000, 0, -0.11430184000000 , 0, 0}, + { 0, 0, -0.11430184000000, 0, 0.58751830000000, -0.76027237000000, 0.23389032000000, 0.08832942000000, 0, -0.03516384000000}}, + {{0, 0, -0.11430184000000, 0, 0.58751830000000, 0.76027237000000, 0.23389032000000, -0.08832942000000, 0, 0.03516384000000}, + {-0.03516384000000, 0, 0.08832942000000, 0.23389032000000, -0.76027237000000, 0.58751830000000, 0, -0.11430184000000, 0, 0}} }; + +//synthesis filter is the reverse (see cplx_wavelet_dec.h) + +/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */ + +const int Haar_len=2;//length of filter +const int Haar_offset=1;//offset + +const float Haar_anal[2][2] = {{0.5,0.5}, {0.5,-0.5}};//analysis filter + +//synthesis filter is the reverse (see cplx_wavelet_dec.h) + +/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */ + +const int LeGall_len=6; +const int LeGall_offset=2; +const float LeGall_anal[2][6] = {{0, 0.25, 0.5, 0.25, 0, 0}, {0, -0.125, -0.25, 0.75, -0.25, -0.125}}; +const float LeGall_synth[2][6] = {{-0.125, 0.25, 0.75, 0.25, -0.125, 0}, {0, 0, -0.25, 0.5, -0.25, 0}}; + +/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */ + +const int Daub4_len=6; +const int Daub4_offset=2; +const float Daub4_anal[2][6] = {//analysis filter + {0, 0, 0.34150635, 0.59150635, 0.15849365, -0.091506351}, + {-0.091506351, -0.15849365, 0.59150635, -0.34150635, 0, 0}}; + +}; + diff --git a/rtengine/cplx_wavelet_level.h b/rtengine/cplx_wavelet_level.h new file mode 100644 index 000000000..a89b91af6 --- /dev/null +++ b/rtengine/cplx_wavelet_level.h @@ -0,0 +1,603 @@ +/* + * 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_LEVEL_H_INCLUDED +#define CPLX_WAVELET_LEVEL_H_INCLUDED + +#include +#include + +#include "gauss.h" +#include "rt_math.h" + +namespace rtengine { + + + ////////////////////////////////////////////////////////////////////////////// + + template + class wavelet_level + { + // full size + size_t m_w, m_h; + + // size of low frequency part + size_t m_w2, m_h2; + + // size of padded border + size_t m_pad; + + // level of decomposition + int lvl; + + // whether to subsample the output + bool subsamp_out; + + // spacing of filter taps + size_t skip; + + // allocation and destruction of data storage + T ** create(size_t n); + void destroy(T ** subbands); + + // load a row/column of input data, possibly with padding + template + void loadbuffer(E * src, E * dst, int srclen, int pitch); + + void AnalysisFilter (T * srcbuffer, T * dstLo, T * dstHi, float *filterLo, float *filterHi, + int taps, int offset, int pitch, int srclen); + void SynthesisFilter (T * srcLo, T * srcHi, T * dst, T *bufferLo, T *bufferHi, + float *filterLo, float *filterHi, int taps, int offset, int pitch, int dstlen); + + void AnalysisFilterHaar (T * srcbuffer, T * dstLo, T * dstHi, int pitch, int srclen); + void SynthesisFilterHaar (T * srcLo, T * srcHi, T * dst, T *bufferLo, T *bufferHi, int pitch, int dstlen); + + void AnalysisFilterSubsamp (T * srcbuffer, T * dstLo, T * dstHi, float *filterLo, float *filterHi, + int taps, int offset, int pitch, int srclen); + void SynthesisFilterSubsamp (T * srcLo, T * srcHi, T * dst, T *bufferLo, T *bufferHi, + float *filterLo, float *filterHi, int taps, int offset, int pitch, int dstlen); + + void AnalysisFilterSubsampHaar (T * srcbuffer, T * dstLo, T * dstHi, int pitch, int srclen); + void SynthesisFilterSubsampHaar (T * srcLo, T * srcHi, T * dst, int pitch, int dstlen); + + void imp_nr (T* src, int width, int height, double thresh); + + + public: + + T ** wavcoeffs; + + template + wavelet_level(E * src, int level, int subsamp, int padding, size_t w, size_t h, float *filterV, float *filterH, int len, int offset) + : m_w(w), m_h(h), m_w2(w), m_h2(h), m_pad(padding), wavcoeffs(NULL), lvl(level), skip(1<>level)&1) + { + if (subsamp) { + skip = 1; + for (int n=0; n>n)&1); + } + } + m_w2 = (subsamp_out ? ((w+1+2*skip*padding)/2) : (w+2*skip*padding)); + m_h2 = (subsamp_out ? ((h+1+2*skip*padding)/2) : (h+2*skip*padding)); + m_pad= skip*padding; + + wavcoeffs = create((m_w2)*(m_h2)); + decompose_level(src, filterV, filterH, len, offset); + + } + + ~wavelet_level() + { + destroy(wavcoeffs); + } + + T ** subbands() const + { + return wavcoeffs; + } + + T * lopass() const + { + return wavcoeffs[0]; + } + + size_t width() const + { + return m_w2; + } + + size_t height() const + { + return m_h2; + } + + size_t padding() const + { + return m_pad/skip; + } + + size_t stride() const + { + return skip; + } + + template + void decompose_level(E *src, float *filterV, float *filterH, int len, int offset); + + template + void reconstruct_level(E *dst, float *filterV, float *filterH, int len, int offset); + + }; + + ////////////////////////////////////////////////////////////////////////////// + + + + template + T ** wavelet_level::create(size_t n) + { + T * data = new T[4*n]; + T ** subbands = new T*[4]; + for(size_t j = 0; j < 4; j++) + { + subbands[j] = data + n * j; + } + return subbands; + } + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + template + void wavelet_level::destroy(T ** subbands) + { + if(subbands) + { + delete[] subbands[0]; + delete[] subbands; + } + } + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + template template + void wavelet_level::loadbuffer(E * src, E * dst, int pitch, int srclen) + { + E * tmp = dst + m_pad; + memset(dst, 0, (MAX(m_w2,m_h2))*sizeof(E)); + + //create padded buffer from src data + for (size_t i = 0, j = 0; i + void wavelet_level::AnalysisFilter (T * srcbuffer, T * dstLo, T * dstHi, float *filterLo, float *filterHi, + int taps, int offset, int pitch, int srclen) { + + /* 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 + * + */ + + + for (size_t i = 0; i < (srclen); i++) { + float lo=0,hi=0; + if (i>skip*taps && i + void wavelet_level::SynthesisFilter (T * srcLo, T * srcHi, T * dst, T *bufferLo, T *bufferHi, float *filterLo, + float *filterHi, int taps, int offset, int pitch, int dstlen) { + + /* 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 + * + */ + + + // load into buffer + + int srclen = (dstlen==m_w ? m_w2 : m_h2);//length of row/col in src (coarser level) + + for (size_t i=0, j=0; iskip*taps && i<(srclen-skip*taps)) {//bulk + for (int j=0, l=-shift; j + void wavelet_level::AnalysisFilterHaar (T * srcbuffer, T * dstLo, T * dstHi, int pitch, int srclen) { + + /* Basic convolution code + * Applies a Haar filter + * + */ + + for(size_t i = 0; i < (srclen - skip); i++) { + dstLo[(pitch*(i))] = 0.5*(srcbuffer[i] + srcbuffer[i+skip]); + dstHi[(pitch*(i))] = 0.5*(srcbuffer[i] - srcbuffer[i+skip]); + } + + for(size_t i = (srclen-skip); i < (srclen); i++) { + dstLo[(pitch*(i))] = 0.5*(srcbuffer[i] + srcbuffer[i-skip]); + dstHi[(pitch*(i))] = 0.5*(srcbuffer[i] - srcbuffer[i-skip]); + } + + } + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + template + void wavelet_level::SynthesisFilterHaar (T * srcLo, T * srcHi, T * dst, T *bufferLo, T *bufferHi, int pitch, int dstlen) { + + /* Basic convolution code + * Applies a Haar filter + * + */ + + int srclen = (dstlen==m_w ? m_w2 : m_h2);//length of row/col in src (coarser level) + + for (size_t i=0, j=0; i + void wavelet_level::AnalysisFilterSubsamp (T * srcbuffer, T * dstLo, T * dstHi, float *filterLo, float *filterHi, + int taps, int offset, int pitch, int srclen) { + + /* 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 < (srclen); i+=2) { + float lo=0,hi=0; + if (i>skip*taps && i + void wavelet_level::SynthesisFilterSubsamp (T * srcLo, T * srcHi, T * dst, T *bufferLo, T *bufferHi, + float *filterLo, float *filterHi, int taps, int offset, int pitch, int dstlen) { + + /* 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 srclen = (dstlen==m_w ? m_w2 : m_h2);//length of row/col in src (coarser level) + + //fill a buffer with a given row/column of data + for (size_t i=0, j=0; iskip*taps && i<(srclen-skip*taps)) {//bulk + for (int j=begin, l=0; j + void wavelet_level::AnalysisFilterSubsampHaar (T * srcbuffer, T * dstLo, T * dstHi, int pitch, int srclen) { + + /* Basic convolution code + * Applies a Haar filter + * Output is subsampled by two + */ + + // calculate coefficients + + for(size_t i = 0; i < (srclen - skip); i+=2) { + dstLo[(pitch*(i/2))] = 0.5*(srcbuffer[i] + srcbuffer[i+skip]); + dstHi[(pitch*(i/2))] = 0.5*(srcbuffer[i] - srcbuffer[i+skip]); + } + + for(size_t i = (srclen-skip)-((srclen-skip)&1); i < (srclen); i+=2) { + dstLo[(pitch*(i/2))] = 0.5*(srcbuffer[i] + srcbuffer[i-skip]); + dstHi[(pitch*(i/2))] = 0.5*(srcbuffer[i] - srcbuffer[i-skip]); + } + + } + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + template + void wavelet_level::SynthesisFilterSubsampHaar (T * srcLo, T * srcHi, T * dst, int pitch, int dstlen) { + + /* Basic convolution code + * Applies a Haar filter + * Input was subsampled by two + */ + + + // calculate coefficients + + //TODO: this code is buggy... + for (int n=0; n template + void wavelet_level::decompose_level(E *src, float *filterV, float *filterH, int taps, int offset) { + + T *tmpLo = new T[m_w*m_h2]; + T *tmpHi = new T[m_w*m_h2]; + + T *buffer = new T[MAX(m_w,m_h)+2*m_pad+skip]; + + /* filter along columns */ +//OpenMP here + for (int j=0; j template + void wavelet_level::reconstruct_level(E *dst, float *filterV, float *filterH, int taps, int offset) { + + T *tmpLo = new T[m_w*m_h2]; + T *tmpHi = new T[m_w*m_h2]; + + int buflen = MAX(m_w2,m_h2); + float *bufferLo = new float[buflen]; + float *bufferHi = new float[buflen]; + + /* filter along rows */ +//OpenMP here + 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 +#include +#include + +#include "rt_math.h" + +#include "mytime.h" +#include "array2D.h" +#include "LUT.h" +#include "curves.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; igetVal (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.0 * lutCurve[i]); + } + } + else { + for (int i=0; i<=0xffff; i++) { + outCurve[i] = (float)i; + } + } + } + +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) +{ + LUTf dcurve(65536,0); + LUTf dCcurve(65536,0); + + float val; + for (int i=0; i<32768; i++) { + val = (double)i / 32767.0; + dcurve[i] = CLIPD(val); + } + for (int i=0; i<48000; i++) { //# 32768*1.414 approximation maxi for chroma + val = (double)i / 47999.0; + dCcurve[i] = CLIPD(val); + } + + 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; + } + } + 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[i] ; + } + } + 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] ; + } + } + + if (tcurve) delete tcurve; + +} + +void CurveFactory::curveBW ( + const std::vector& curvePointsbw, const std::vector& curvePointsbw2, + LUTu & histogrambw, LUTu & outBeforeCCurveHistogrambw,//for Luminance + ToneCurve & customToneCurvebw1, ToneCurve & customToneCurvebw2, int skip) +{ + LUTf dcurve(65536,0); + + float val; + for (int i=0; i<32768; i++) { + val = (double)i / 32767.0; + dcurve[i] = CLIPD(val); + } + + 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 + + for (int i=0; i<=32768; i++) { + float val; + + if (histNeeded) { + 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; + LUTf dCcurve(65536,0); + + float val; + for (int i=0; i<50000; i++) { //# 32768*1.414 approximation maxi for chroma + dCcurve[i] = (float)i / 49999.0; + } + + 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;} + } + for (int i=0; i<=50000; i++) {//32768*1.414 + ... + float val; + if (histNeededCL) { + float hval = dCcurve[i]; + int hi = (int)(255.0*CLIPD(hval)); // + outBeforeCLurveHistogram[hi] += histogramcl[i] ; + } + } + + fillCurveArray(dCurve, clCurve, skip, needed); + if (dCurve) { + delete dCurve; + dCurve = NULL; + } +} + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + void CurveFactory::complexsgnCurve ( 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); + + for (int i=0; i<48000; i++) { //# 32768*1.414 approximation maxi for chroma + dCcurve[i] = (float)i / 47999.0; + } + if (outBeforeCCurveHistogram) + outBeforeCCurveHistogram.clear(); + bool histNeededC = false; + + if (outBeforeLCurveHistogram) + outBeforeLCurveHistogram.clear(); + bool histNeededLC = false; + + //----------------------------------------------------- + + needed = false; + // create a curve if needed + if (!acurvePoints.empty() && acurvePoints[0]!=0) { + dCurve = new DiagonalCurve (acurvePoints, CURVES_MIN_POLY_POINTS/skip); + if (dCurve && !dCurve->isIdentity()) { + 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;} + } + 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)); // + outBeforeCCurveHistogram[hi] += histogramC[i] ; + } + } + + fillCurveArray(dCurve, satCurve, skip, needed); + if (dCurve) { + delete dCurve; + dCurve = NULL; + } + //---------------------------- + needed = false; + if (!lccurvePoints.empty() && lccurvePoints[0]!=0) { + dCurve = new DiagonalCurve (lccurvePoints, CURVES_MIN_POLY_POINTS/skip); + if (outBeforeLCurveHistogram /*&& histogramCropped*/) + histNeededLC = true; + + if (dCurve && !dCurve->isIdentity()) + {needed = true;cclutili=true;} + } + for (int i=0; i<=48000; i++) {//32768*1.414 + ... + float val; + if (histNeededLC) { + float hval = dCcurve[i]; + int hi = (int)(255.0*CLIPD(hval)); // + outBeforeLCurveHistogram[hi] += histogramLC[i] ; + } + } + + + fillCurveArray(dCurve, lhskCurve, skip, needed); + if (dCurve) { + delete dCurve; + dCurve = NULL; + } + + } + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + void CurveFactory::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 & 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); + + // curve without contrast + LUTf dcurve(0x10000); + + // 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); + } + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + 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); + + for (int i=0; i<0x10000; i++) { + + // change to [0,1] range + float val = (float)i-shoulder; + + if (comp>0.0) + { + if (val>0.0) { + float R = val*comp/(scale-shoulder); + hlCurve[i] = log(1.0+R*exp_scale)/R; + } else { + hlCurve[i]=exp_scale; + } + } else { + hlCurve[i]=exp_scale; + } + + //%%%%%%%%%%%%%%%%%%%%%%%%%% + // change to [0,1] range + if (i!=0) { + val = (float)i / 65535.0f; + } else { + val = 1.0/65535.0; + } + + float val2 = basecurve (val, 1.0, black, 1.0, 0.0, 1.5*shcompr/100.0); + shCurve[i] = CLIPD(val2)/val; + + //%%%%%%%%%%%%%%%%%%%%%%%%%% + // change to [0,1] range + val = (double)i / 65535.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[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 + int sum = 0; + float avg = 0; + //double sqavg = 0; + for (int i=0; i<=0xffff; i++) { + float fi=i; + fi = hlCurve[fi]*fi; + 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()) { + delete tcurve; + tcurve = NULL; + } + else + customToneCurve2.Set(tcurve); + delete tcurve; + tcurve = NULL; + } + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + // create first curve if needed + customToneCurve1.Reset(); + + if (!curvePoints.empty() && curvePoints[0]>DCT_Linear && curvePoints[0]isIdentity()) { + delete tcurve; + tcurve = NULL; + } + else if (curveMode != procparams::ToneCurveParams::TC_MODE_STD) { + 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; + + 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] ; + } + + // apply custom/parametric/NURBS curve, if any + if (tcurve) { + val = tcurve->getVal (dcurve[i]); // TODO: getVal(double) is very slow! Optimize with a LUTf + } else { + val = dcurve[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.0 * 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; + + // 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]; + } + 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 + + DiagonalCurve* 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.; +} + +} diff --git a/rtengine/curves.h b/rtengine/curves.h new file mode 100644 index 000000000..17efa202e --- /dev/null +++ b/rtengine/curves.h @@ -0,0 +1,655 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 "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)/2) / (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 + 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; + } + } + + + 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); + float Y = val*exp_scale/hlrange; + float R = hlrange/(val*comp); + return log(1.0+Y*comp)*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 complexsgnCurve ( 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 (); + 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; + + unsigned int minSearch; // a effacer!!! + unsigned int maxSearch; // a effacer!!! + unsigned int searchArray[21]; // a effacer!!! + + 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 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 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)); +} + +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..18b72810c --- /dev/null +++ b/rtengine/dcp.cc @@ -0,0 +1,949 @@ +/* +* 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 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); +} + +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, 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 + + 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; + if (wb.getTemp() <= temperature1) { + mix = 1.0; + } else if (wb.getTemp() >= temperature2) { + mix = 0.0; + } else { + double invT = 1.0 / wb.getTemp(); + mix = (invT - (1.0 / temperature2)) / ((1.0 / temperature1) - (1.0 / temperature2)); + } + + 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)); + } + ConvertDNGForwardMatrix2XYZCAM(mFwd,mXYZCAM,wb); + } else { + // 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)); + } + ConvertDNGMatrix2XYZCAM(mCol,mXYZCAM); + } +} + +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 TagProfileToneCurve=50940; + + 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; + tag = tagDir->getTag(TagForwardMatrix1); + if (tag) { + hasForwardMatrix1 = true; + for (int row=0;row<3;row++) { + for (int col=0;col<3;col++) { + mForwardMatrix1[col][row]=(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[col][row]=(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[col][row]=(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(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(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[col][row]= (tag!=NULL ? (float)tag->toDouble((col+row*3)*8) : mColorMatrix1[col][row]); + } + } + + // 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); + } + } + } + + // Read tone curve points, if any, but disable to RTs own profiles + // the DCP tone curve is subjective and of low quality in comparison to RTs tone curves + 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; + } + } + + 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; + } + } + } else 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; +} + +// Convert DNG color matrix to xyz_cam compatible matrix +void DCPProfile::ConvertDNGMatrix2XYZCAM(const double (*mColorMatrix)[3], double (*mXYZCAM)[3]) const { + int i,j,k; + + double cam_xyz[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_xyz[i][j] += mColorMatrix[j][k] * (i==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]; +} + +void DCPProfile::HSDApply(const HSDTableInfo &ti, const HSBModify *tableBase, const float hs, const float ss, const float vs, float &h, float &s, float &v) const { + + // Apply the HueSatMap. Ported from Adobes reference implementation + float hueShift, satScale, valScale; + + if (ti.iValDivisions < 2) // Optimize most common case of "2.5D" table. + { + float hScaled = hs * ti.pc.hScale; + float sScaled = ss * 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 = hs * ti.pc.hScale; + float sScaled = ss * ti.pc.sScale; + float vScaled = vs * 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 :-) + v *= valScale; +} + +// Convert DNG forward matrix to xyz_cam compatible matrix +void DCPProfile::ConvertDNGForwardMatrix2XYZCAM(const double (*mForwardMatrix)[3], double (*mXYZCAM)[3], ColorTemp &wb) const { + + // Convert ForwardMatrix (white-balanced CameraRGB -> XYZ D50 matrix) + // into a ColorMatrix (XYZ -> CameraRGB) + + double X, Z; + ColorTemp::temp2mulxyz(wb.getTemp(), wb.getGreen(), wb.getMethod(), X, Z); + + const double white_xyz[3] = { X, 1, Z }; + const double white_d50[3] = { 0.3457, 0.3585, 0.2958 }; // D50 + + // Cancel out the white balance to get a CameraRGB -> XYZ D50 matrixx (CameraToPCS in dng terminology) + double whiteDiag[3][3] = {{white_xyz[0], 0, 0}, {0, white_xyz[1], 0}, {0, 0, white_xyz[2]}}; + double whiteDiagInv[3][3]; + Invert3x3(whiteDiag, whiteDiagInv); + double rgb2xyzD50[3][3]; + Multiply3x3(mForwardMatrix, whiteDiagInv, rgb2xyzD50); + + // Through chromatic adaptation convert XYZ D50 to XYZ camera white + double whiteMatrix[3][3]; + MapWhiteMatrix(white_d50, white_xyz, whiteMatrix); + double rgb2xyz[3][3]; + Multiply3x3(rgb2xyzD50, whiteMatrix, rgb2xyz); + + // Now we have CameraRGB -> XYZ, invert so we get XYZ -> CameraRGB (ColorMatrix format) + double dngColorMatrix[3][3]; + Invert3x3(rgb2xyz, dngColorMatrix); + + // now we can run the ordinary ColorMatrix conversion + ConvertDNGMatrix2XYZCAM(dngColorMatrix, mXYZCAM); +} + +void DCPProfile::Apply(Imagefloat *pImg, int preferredIlluminant, Glib::ustring workingSpace, ColorTemp &wb, float rawWhiteFac, bool useToneCurve) const { + + TMatrix mWork = iccStore->workingSpaceInverseMatrix (workingSpace); + + double mXYZCAM[3][3]; + MakeXYZCAM(wb, preferredIlluminant, mXYZCAM); + HSBModify *deleteTableHandle; + const HSBModify *deltaBase = MakeHueSatMap(wb, preferredIlluminant, &deleteTableHandle); + + useToneCurve&=toneCurve; + + if (deltaBase == NULL && aLookTable == NULL && !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]; + + bool useRawWhite=fabs(rawWhiteFac)>0.001; + + // 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 ((deltaBase || aLookTable) && newr>=0 && newg>=0 && newb>=0) { + Color::rgb2hsv(newr, newg, newb, h , s, v); + h*=6.f; // RT calculates in [0,1] + + if (useRawWhite) { + // Retro-calculate what the point was like before RAW white came in + Color::rgb2hsv(newr/rawWhiteFac, newg/rawWhiteFac, newb/rawWhiteFac, hs, ss, vs); + hs*=6.f; // RT calculates in [0,1] + } else { + hs=h; ss=s; vs=v; + } + + if (deltaBase) { + HSDApply(DeltaInfo, deltaBase, hs, ss, vs, h, s, v); + } + if (aLookTable) { + HSDApply(LookInfo, aLookTable, hs, ss, vs, 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; +} + +// Integer variant is legacy, only used for thumbs. Simply take the matrix here +void DCPProfile::Apply(Image16 *pImg, int preferredIlluminant, Glib::ustring workingSpace, ColorTemp &wb, bool useToneCurve) const { + TMatrix mWork = iccStore->workingSpaceInverseMatrix (workingSpace); + + double mXYZCAM[3][3]; + MakeXYZCAM(wb, preferredIlluminant, mXYZCAM); + + useToneCurve&=toneCurve; + + // 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); + + // tone curve + if (useToneCurve) toneCurve.Apply(newr, newg, newb); + + pImg->r(y,x) = CLIP((int)newr); pImg->g(y,x) = CLIP((int)newg); pImg->b(y,x) = CLIP((int)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..b7a3fdbbc --- /dev/null +++ b/rtengine/dcp.h @@ -0,0 +1,100 @@ +/* +* 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; + 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, willInterpolate; + double mForwardMatrix1[3][3],mForwardMatrix2[3][3]; + double temperature1, temperature2; + HSBModify *aDeltas1,*aDeltas2,*aLookTable; + HSDTableInfo DeltaInfo,LookInfo; + short iLightSource1,iLightSource2; + + AdobeToneCurve toneCurve; + + void MakeXYZCAM(ColorTemp &wb, int preferredIlluminant, double (*mXYZCAM)[3]) const; + const HSBModify* MakeHueSatMap(ColorTemp &wb, int preferredIlluminant, HSBModify **deleteHandle) const; + void ConvertDNGMatrix2XYZCAM(const double (*mColorMatrix)[3], double (*mXYZCAM)[3]) const; + void ConvertDNGForwardMatrix2XYZCAM(const double (*mForwardMatrix)[3], double (*mXYZCAM)[3], ColorTemp &wb) const; + void HSDApply(const HSDTableInfo &ti, const HSBModify *tableBase, const float hs, const float ss, const float vs, float &h, float &s, float &v) const; + + public: + DCPProfile(Glib::ustring fname, bool isRTProfile); + ~DCPProfile(); + + bool getHasToneCurve() { return hasToneCurve; } + 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, float rawWhiteFac=1, bool useToneCurve=false) const; + void Apply(Image16 *pImg, int preferredIlluminant, Glib::ustring workingSpace, ColorTemp &wb, bool useToneCurve) 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..32002d76a --- /dev/null +++ b/rtengine/dcraw.c @@ -0,0 +1,9424 @@ +/* + dcraw.c -- Dave Coffin's raw photo decoder + Copyright 1997-2013 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.456 $ + $Date: 2013/06/16 18:01:08 $ + */ + +#define DCRAW_VERSION "9.19" + +#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]; +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, cblack[4], 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]; +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, black, black_off, split_col, tag_21a; + 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+top_margin+6)%6][(col+left_margin+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 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]*jh.high); + if ((j = i >= cr2_slice[0])) + i = cr2_slice[0]; + jidx -= i * (cr2_slice[1]*jh.high); + 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); +} + +/* + 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, y, x, c, rend, cend, row, col; + float *mrow, num, mult[4]; + + read_shorts (head, 8); + wide = head[2] / head[4]; + mrow = (float *) calloc (nc*wide, sizeof *mrow); + merror (mrow, "phase_one_flat_field()"); + for (y=0; y < head[3] / head[5]; 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++) { + 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++) { + 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]; + + 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) /* 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; + } + } + 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 (*black)[2]; + + pixel = (ushort *) calloc (raw_width + 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(); + black = (short (*)[2]) offset + raw_height; + fseek (ifp, ph1.black_off, SEEK_SET); + if (ph1.black_off) + read_shorts ((ushort *) black[0], raw_height*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 + black[row][col >= ph1.split_col]; + if (i > 0) RAW(row,col) = i; + } + } + free (pixel); + maximum = 0xfffc - ph1.black; +} + +void CLASS hasselblad_load_raw() +{ + struct jhead jh; + int row, col, pred[2], len[2], diff, c; + + if (!ljpeg_start (&jh, 0)) return; + order = 0x4949; + ph1_bits(-1); + for (row=0; row < raw_height; row++) { + pred[0] = pred[1] = 0x8000 + load_flags; + for (col=0; col < raw_width; col+=2) { + FORC(2) len[c] = ph1_huff(jh.huff[0]); + FORC(2) { + diff = ph1_bits(len[c]); + if ((diff & (1 << (len[c]-1))) == 0) + diff -= (1 << len[c]) - 1; + if (diff == 65535) diff = -32768; + RAW(row,col+c) = pred[c] += diff; + } + } + } + ljpeg_end (&jh); + maximum = 0xffff; +} + +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 ((shot = shot_select) || half_size) { + if (shot) shot--; + if (shot > 3) shot = 3; + fseek (ifp, data_offset + shot*4, SEEK_SET); + fseek (ifp, get4(), SEEK_SET); + unpacked_load_raw(); + return; + } + free (raw_image); + raw_image = 0; + free (image); + image = (ushort (*)[4]) + calloc ((iheight=height), (iwidth=width)*sizeof *image); + merror (image, "sinar_4shot_load_raw()"); + 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][FC(row,col)] = pixel[col]; + } + } + } + free (pixel); + shrink = filters = 0; +} + +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) && col < width+left_margin) derror(); + } + vbits -= rbits; + } +} + +void CLASS nokia_load_raw() +{ + uchar *data, *dp; + int rev, dwide, row, col, c; + + 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; +} + +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) = bits >> (10*c+2) & 0x3ff; + } + } + maximum = 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]) + huff[0][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++) + buf[0][0][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++) + buf[c][0][i] = (buf[c][0][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 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 curve[3][256]; + double coeff[9], tot; + + 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); + curve[c][i] = tot*0xffff; + } + } + order = sorder; + 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] = curve[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_yrgb_load_raw() +{ + uchar *pixel; + int row, col, y, cb, cr, rgb[3], c; + + pixel = (uchar *) calloc (raw_width, 3*sizeof *pixel); + merror (pixel, "kodak_yrgb_load_raw()"); + for (row=0; row < height; row++) { + if (~row & 1) + if (fread (pixel, raw_width, 3, ifp) < 3) derror(); + for (col=0; col < raw_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]; + + if (raw_image) free (raw_image); + raw_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--) + *data++ ^= pad[p++ & 127] = pad[(p+1) & 127] ^ pad[(p+65) & 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 int *) 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 int *) 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[32768]; + 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, len, diff, sum=0; + + 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; + len = getbithuff(15,huff); + diff = getbits(len); + if ((diff & (1 << (len-1))) == 0) + diff -= (1 << len) - 1; + if ((sum += diff) >> 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); + 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; + } + } + } +} + +#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 = fgetc(ifp); + fseek (ifp, offset, SEEK_SET); + for (i=0; i < nseg*2; i++) + seg[0][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++) + ddft[0][0][i] = ddft[1][0][i] + + row / (height-1.0) * (ddft[2][0][i] - ddft[1][0][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++) + ddft[0][0][i] = ddft[1][0][i] + + row / (height-1.0) * (ddft[2][0][i] - ddft[1][0][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 int *) 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]) 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]; +} + +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 (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 (raw_color = 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], num; + int c, i, j, k, sq, row, col, 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] += BAYER(row,col); + 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 (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 (cam_xyz); + 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); + } + size = iheight*iwidth; + for (i=0; i < size*4; i++) { + val = image[0][i]; + if (!val) continue; + val -= cblack[i & 3]; + val *= scale_mul[i & 3]; + image[0][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+top_margin+6)%6][(col+left_margin+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); + border_interpolate(6); + 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+1; row < mrow-1; row++) + for (col=left+1; col < mcol-1; col++) { + if ((f = 2-fcol(row,col)) == 1) continue; + rix = &rgb[0][row-top][col-left]; + i = (row-sgrow) % 3 ? TS:1; + for (d=0; d < 4; d++, rix += TS*TS) + 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); +} +#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 * ("11124811248488"[*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")) { + base = ftell(ifp)-10; + fseek (ifp, -2, SEEK_CUR); + order = get2(); 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 == 0x81 && type == 4) { + data_offset = get4(); + fseek (ifp, data_offset + 41, SEEK_SET); + raw_height = get2() * 2; + raw_width = get2(); + filters = 0x61616161; + } + 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 == 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) + 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 ? 112:22; + fseek (ifp, i, SEEK_CUR); + FORC4 sraw_mul[c ^ (c >> 1)] = get2(); + } + if (tag == 0xa021) + FORC4 cam_mul[c ^ (c >> 1)] = get4(); + if (tag == 0xa028) + FORC4 cam_mul[c ^ (c >> 1)] -= get4(); +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 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++) + romm_cam[0][i] = int_to_float(get4()); + romm_coeff (romm_cam); + } + if (!strcmp(data,"CaptProf_color_matrix")) { + for (i=0; i < 9; i++) + fscanf (ifp, "%f", &romm_cam[0][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 == 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; + int blrr=1, blrc=1, dblack[] = { 0,0,0,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 36: case 37: case 38: + cam_mul[tag-0x24] = 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 */ + 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; + 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 == 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 33422: /* CFAPattern */ + 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(); + load_raw = &CLASS samsung_load_raw; + 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 (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 */ + blrr = get2(); + blrc = get2(); + break; + case 61450: + blrr = blrc = 2; + case 50714: /* BlackLevel */ + black = getreal(type); + if ((unsigned)(filters+1) < 1000) break; + dblack[0] = black; + dblack[1] = (blrc == 2) ? getreal(type):dblack[0]; + dblack[2] = (blrr == 2) ? getreal(type):dblack[0]; + dblack[3] = (blrc == 2 && blrr == 2) ? getreal(type):dblack[1]; + if (colors == 3) + filters |= ((filters >> 2 & 0x22222222) | + (filters << 2 & 0x88888888)) & filters << 1; + FORC4 cblack[filters >> (c << 1) & 3] = dblack[c]; + 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++) + mask[0][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 (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*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 != 32769 && tiff_compress != 32770) + || (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++) + romm_cam[0][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_off = 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[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) + 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_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++) + poff[0][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 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", 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 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 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 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 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 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 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 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 S200EXR", 512, 0x3fff, + { 11401,-4498,-1312,-5088,12751,2613,-838,1568,5941 } }, + { "Fujifilm S20Pro", 0, 0, + { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } }, + { "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 HS20EXR", 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 X100S", 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 X-Pro1", 0, 0, + { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, + { "Fujifilm X-E1", 0, 0, + { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, + { "Fujifilm XF1", 0, 0, + { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, + { "Fujifilm X-S1", 0, 0, + { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, + { "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 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 D4", 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 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 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 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 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", 0, 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 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 ", 0, 0, + { 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-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-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-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 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 ov5647", 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-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 645D", 0, 0x3e00, + { 10646,-3593,-1158,-3329,11699,1831,-667,2874,6287 } }, + { "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", 143, 0, + { 9938,-2780,-890,-4604,12393,2480,-1117,2304,4620 } }, + { "Panasonic DMC-FZ4", 143, 0, + { 13639,-5535,-1371,-1698,9633,2430,316,1152,4108 } }, + { "Panasonic DMC-FZ50", 0, 0, + { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } }, + { "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-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", 143, 0, + { 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } }, + { "Leica D-LUX 5", 143, 0, + { 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } }, + { "Panasonic DMC-LX7", 143, 0, + { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } }, + { "Leica D-LUX 6", 143, 0, + { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } }, + { "Panasonic DMC-FZ100", 143, 0xfff, + { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } }, + { "Leica V-LUX 2", 143, 0xfff, + { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } }, + { "Panasonic DMC-FZ150", 143, 0xfff, + { 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } }, + { "Leica V-LUX 3", 143, 0xfff, + { 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } }, + { "Panasonic DMC-FZ200", 143, 0xfff, + { 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } }, + { "Leica V-LUX 4", 143, 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", 143, 0xfff, + { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } }, + { "Panasonic DMC-G5", 143, 0xfff, + { 7798,-2562,-740,-3879,11584,2613,-1055,2248,5434 } }, + { "Panasonic DMC-G6", 143, 0xfff, /* DJC */ + { 6395,-2583,-40,-3677,9109,4569,-1502,2806,6431 } }, + { "Panasonic DMC-GF1", 15, 0xf92, + { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } }, + { "Panasonic DMC-GF2", 143, 0xfff, + { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } }, + { "Panasonic DMC-GF3", 143, 0xfff, + { 9051,-2468,-1204,-5212,13276,2121,-1197,2510,6890 } }, + { "Panasonic DMC-GF5", 143, 0xfff, + { 8228,-2945,-660,-3938,11792,2430,-1094,2278,5793 } }, + { "Panasonic DMC-GF6", 143, 0, + { 8130,-2801,-946,-3520,11289,2552,-1314,2511,5791 } }, + { "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", 144, 0, + { 6559,-1752,-491,-3672,11407,2586,-962,1875,5130 } }, + { "Panasonic DMC-GX1", 143, 0, + { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } }, + { "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 NX300", 0, 0, + { 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 NX", 0, 0, /* NX5, NX10, NX11, NX100 */ + { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } }, + { "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 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-RX100", 200, 0, + { 8651,-2754,-1057,-3464,12207,1373,-568,1398,4434 } }, + { "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-A5", 128, 0xfeb, + { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } }, + { "Sony DSLR-A700", 126, 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 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-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 (j=0; j < 12; j++) + cam_xyz[0][j] = table[i].trans[j] / 10000.0; + cam_xyz_coeff (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[][6] = { + { 1944, 1416, 0, 0, 48, 0 }, + { 2144, 1560, 4, 8, 52, 2 }, + { 2224, 1456, 48, 6, 0, 2 }, + { 2376, 1728, 12, 6, 52, 2 }, + { 2672, 1968, 12, 6, 44, 2 }, + { 3152, 2068, 64, 12, 0, 0 }, + { 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 }, + { 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 }, + { 4312, 2876, 22, 18, 0, 2 }, + { 4352, 2874, 62, 18, 0, 0 }, + { 4476, 2954, 90, 34, 0, 0 }, + { 4480, 3348, 12, 10, 36, 12 }, + { 4496, 3366, 80, 50, 12, 0 }, + { 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 }, + { 5712, 3774, 62, 20, 10, 2 }, + { 5792, 3804, 158, 51, 0, 0 }, + { 5920, 3950, 122, 80, 2, 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" }, + { 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" }, + { 0x346, "EOS 100D" }, + }; + 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" }, + { 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, 8,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" }, + { 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","640x480" }, + { 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 }, + { 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" }, + { 614400, 640, 480, 0, 3, 0, 0,64,0x94,0,0,"Kodak","KAI-0340" }, + { 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","3072x2048",68 }, + { 33292868,4080,4080, 0, 0, 0, 0,33,0x61,0,0,"Sinar","4080x4080",68 }, + { 44390468,4080,5440, 0, 0, 0, 0,33,0x61,0,0,"Sinar","4080x5440",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_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,"\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"); + strcpy (model, "X2"); + order = 0x4949; + fseek (ifp, 300, SEEK_SET); + data_offset = get4(); + i = get4(); + width = get2(); + height = get2(); + data_offset += i - width * 5 / 4 * height; + load_raw = &CLASS nokia_load_raw; + 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; + } 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) && !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; + 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 == 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]; + } + 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 (!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); + 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[0][0] = top_margin = 16; + mask[0][2] = top_margin + height; + mask[0][3] = left_margin = 92; + } else if (!strcmp(model,"PowerShot SX50 HS")) { + mask[0][0] = top_margin = 17; + mask[0][2] = raw_height; + mask[0][3] = 80; + filters = 0x49494949; + } else if (!strcmp(model,"PowerShot G10")) { + filters = 0x49494949; + } 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") || + !strcmp(model,"D600") || + !strncmp(model,"D800",4)) { + width -= 46; + } else if (!strcmp(model,"D4")) { + 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 (!strcmp(make,"Nikon") && raw_width == 4032) { + adobe_coeff ("Nikon","COOLPIX P7700"); + } else if (!strncmp(model,"COOLPIX P",9)) { + 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")) { + width += 2; + left_margin = 0; + filters = 0x16161616; + } + if (fuji_layout) raw_width *= is_raw; + } 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 -= 18; + width = 5536; + filters = 0x49494949; + } 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(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) { + height = 5502; + width = 7328; + 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; + } + } else if (!strcmp(make,"Sinar")) { + if (!load_raw) load_raw = &CLASS unpacked_load_raw; + 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 (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) { + adobe_coeff ("Sony","DSC-R1"); + width = 3925; + order = 0x4d4d; + } else if (!strcmp(make,"Sony") && raw_width == 5504) { + width -= 8; + } else if (!strcmp(make,"Sony") && raw_width == 6048) { + width -= 24; + } else if (!strcmp(model,"DSLR-A100")) { + if (width == 3880) { + height--; + width = ++raw_width; + } else { + 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")) { + order = 0x4949; + if (filters && data_offset) { + fseek (ifp, 168, SEEK_SET); + read_shorts (curve, 256); + } else gamma_curve (0, 3.875, 1, 255); + load_raw = filters ? &CLASS eight_bit_load_raw + : &CLASS kodak_yrgb_load_raw; + } 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)) { + width -= 4; + left_margin = 2; + } else if (!strcmp(model,"EOSDCS3B")) { + width -= 4; + left_margin = 2; + } else if (!strcmp(model,"EOSDCS1")) { + width -= 4; + left_margin = 2; + } else if (!strcmp(model,"DCS420")) { + width -= 4; + left_margin = 2; + } else if (!strncmp(model,"DCS460 ",7)) { + model[6] = 0; + width -= 4; + left_margin = 2; + } else if (!strcmp(model,"DCS460A")) { + width -= 4; + left_margin = 2; + colors = 1; + filters = 0; + } else if (!strcmp(model,"DCS660M")) { + black = 214; + colors = 1; + filters = 0; + } else if (!strcmp(model,"DCS760M")) { + 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 (raw_color) adobe_coeff (make, model); + if (load_raw == &CLASS kodak_radc_load_raw) + if (raw_color) adobe_coeff ("Apple","Quicktake"); + 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 (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 > 4 || 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; + + cmsErrorAction (LCMS_ERROR_SHOW); + 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 = (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 (use_camera_matrix < 0) + use_camera_matrix = use_camera_wb; + 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; + } 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) { + printf (_("\nFilter pattern: ")); + for (i=0; i < 16; i++) + putchar (cdesc[fcol(i >> 1,i & 1)]); + } + 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 (use_camera_matrix && cmatrix[0][0] > 0.25) { + memcpy (rgb_cam, cmatrix, sizeof cmatrix); + raw_color = 0; + } + 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; + 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..5e981627b --- /dev/null +++ b/rtengine/dcraw.cc @@ -0,0 +1,8340 @@ +/*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-2013 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.456 $ + $Date: 2013/06/16 18:01:08 $ + */ + +#define DCRAW_VERSION "9.19" + +#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 + +#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+top_margin+6)%6][(col+left_margin+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*/ 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 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, 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]*jh.high); + if ((j = i >= cr2_slice[0])) + i = cr2_slice[0]; + jidx -= i * (cr2_slice[1]*jh.high); + 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); +} + +/* + 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, y, x, c, rend, cend, row, col; + float *mrow, num, mult[4]; + + read_shorts (head, 8); + wide = head[2] / head[4]; + mrow = (float *) calloc (nc*wide, sizeof *mrow); + merror (mrow, "phase_one_flat_field()"); + for (y=0; y < head[3] / head[5]; 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++) { + 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++) { + 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]; + + 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) /* 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; + } + } + 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 (*black)[2]; + + pixel = (ushort *) calloc (raw_width + 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(); + black = (short (*)[2]) offset + raw_height; + fseek (ifp, ph1.black_off, SEEK_SET); + if (ph1.black_off) + read_shorts ((ushort *) black[0], raw_height*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 + black[row][col >= ph1.split_col]; + if (i > 0) RAW(row,col) = i; + } + } + free (pixel); + maximum = 0xfffc - ph1.black; +} + +void CLASS hasselblad_load_raw() +{ + struct jhead jh; + int row, col, pred[2], len[2], diff, c; + + if (!ljpeg_start (&jh, 0)) return; + order = 0x4949; + ph1_bits(-1); + for (row=0; row < raw_height; row++) { + pred[0] = pred[1] = 0x8000 + load_flags; + for (col=0; col < raw_width; col+=2) { + FORC(2) len[c] = ph1_huff(jh.huff[0]); + FORC(2) { + diff = ph1_bits(len[c]); + if ((diff & (1 << (len[c]-1))) == 0) + diff -= (1 << len[c]) - 1; + if (diff == 65535) diff = -32768; + RAW(row,col+c) = pred[c] += diff; + } + } + } + ljpeg_end (&jh); + maximum = 0xffff; +} + +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 ((shot = shot_select) || half_size) { + if (shot) shot--; + if (shot > 3) shot = 3; + fseek (ifp, data_offset + shot*4, SEEK_SET); + fseek (ifp, get4(), SEEK_SET); + unpacked_load_raw(); + return; + } + free (raw_image); + raw_image = 0; + free (image); + image = (ushort (*)[4]) + calloc ((iheight=height), (iwidth=width)*sizeof *image); + merror (image, "sinar_4shot_load_raw()"); + 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][FC(row,col)] = pixel[col]; + } + } + } + free (pixel); + shrink = filters = 0; +} + +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) && col < width+left_margin) derror(); + } + vbits -= rbits; + } +} + +void CLASS nokia_load_raw() +{ + uchar *data, *dp; + int rev, dwide, row, col, c; + + 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; +} + +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) = bits >> (10*c+2) & 0x3ff; + } + } + maximum = 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]) + huff[0][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++) + buf[0][0][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++) + buf[c][0][i] = (buf[c][0][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 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 curve[3][256]; + double coeff[9], tot; + + 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); + curve[c][i] = tot*0xffff; + } + } + order = sorder; + 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] = curve[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_yrgb_load_raw() +{ + uchar *pixel; + int row, col, y, cb, cr, rgb[3], c; + + pixel = (uchar *) calloc (raw_width, 3*sizeof *pixel); + merror (pixel, "kodak_yrgb_load_raw()"); + for (row=0; row < height; row++) { + if (~row & 1) + if (fread (pixel, raw_width, 3, ifp) < 3) derror(); + for (col=0; col < raw_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]; + + if (raw_image) free (raw_image); + raw_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--){ + *data++ ^= pad[p & 127] = pad[(p+1) & 127] ^ pad[(p+65) & 127]; + p++; + } +} + +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 int *) 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 int *) 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[32768]; + 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, len, diff, sum=0; + + 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; + len = getbithuff(15,huff); + diff = getbits(len); + if ((diff & (1 << (len-1))) == 0) + diff -= (1 << len) - 1; + if ((sum += diff) >> 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); + data = (uchar *) malloc (raw_width + 1); // RT: added +1 to avoid buffer overrun + 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; + } + } + } +} + +#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 = fgetc(ifp); + fseek (ifp, offset, SEEK_SET); + for (i=0; i < nseg*2; i++) + seg[0][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]; + } + } +} + +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++) + ddft[0][0][i] = ddft[1][0][i] + + row / (height-1.0) * (ddft[2][0][i] - ddft[1][0][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++) + ddft[0][0][i] = ddft[1][0][i] + + row / (height-1.0) * (ddft[2][0][i] - ddft[1][0][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 int *) 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]) 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]; +} + +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 (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 (raw_color = 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], num; + int c, i, j, k, sq, row, col, 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] += BAYER(row,col); + 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 (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 (cam_xyz); + 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); + } + size = iheight*iwidth; + for (i=0; i < size*4; i++) { + val = image[0][i]; + if (!val) continue; + val -= cblack[i & 3]; + val *= scale_mul[i & 3]; + image[0][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+top_margin+6)%6][(col+left_margin+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); + border_interpolate(6); + 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+1; row < mrow-1; row++) + for (col=left+1; col < mcol-1; col++) { + if ((f = 2-fcol(row,col)) == 1) continue; + rix = &rgb[0][row-top][col-left]; + i = (row-sgrow) % 3 ? TS:1; + for (d=0; d < 4; d++, rix += TS*TS) + 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); +} +#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 * ("11124811248488"[*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")) { + base = ftell(ifp)-10; + fseek (ifp, -2, SEEK_CUR); + order = get2(); 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 == 0x81 && type == 4) { + data_offset = get4(); + fseek (ifp, data_offset + 41, SEEK_SET); + raw_height = get2() * 2; + raw_width = get2(); + filters = 0x61616161; + } + 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 == 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) + 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 ? 112:22; + fseek (ifp, i, SEEK_CUR); + FORC4 sraw_mul[c ^ (c >> 1)] = get2(); + } + if (tag == 0xa021) + FORC4 cam_mul[c ^ (c >> 1)] = get4(); + if (tag == 0xa028) + FORC4 cam_mul[c ^ (c >> 1)] -= get4(); +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 6","","","Aptus-II 10","Aptus-II 5","","","","","Aptus-II 10R","Aptus-II 8","","Aptus-II 12","","AFi-II 12" }; // RT: added missing model names + 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++) + romm_cam[0][i] = int_to_float(get4()); + romm_coeff (romm_cam); + } + if (!strcmp(data,"CaptProf_color_matrix")) { + for (i=0; i < 9; i++) + fscanf (ifp, "%f", &romm_cam[0][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) /* RT: wb tag for DCS760 */ + FORC3 cam_mul[c] = 2048.0 / getreal(type); /* RT: wb tag for DCS760 */ + 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; + int blrr=1, blrc=1, dblack[] = { 0,0,0,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; +/*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; + 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 36: case 37: case 38: + cam_mul[tag-0x24] = 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 */ + 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; + 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 == 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 33422: /* CFAPattern */ + 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(); + load_raw = &CLASS samsung_load_raw; + 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 (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 */ + blrr = get2(); + blrc = get2(); + break; + case 61450: + blrr = blrc = 2; + if (filters == UINT_MAX) filters = 0x94949494; /* RT: Fuji X100 fix for dcraw 9.19 to get proper black level parsing, hopefully works for other Fuji cameras too! */ + case 50714: /* BlackLevel */ + black = getreal(type); + if ((unsigned)(filters+1) < 1000) break; + dblack[0] = black; + dblack[1] = (blrc == 2) ? getreal(type):dblack[0]; + dblack[2] = (blrr == 2) ? getreal(type):dblack[0]; + dblack[3] = (blrc == 2 && blrr == 2) ? getreal(type):dblack[1]; + if (colors == 3) + filters |= ((filters >> 2 & 0x22222222) | + (filters << 2 & 0x88888888)) & filters << 1; + FORC4 cblack[filters >> (c << 1) & 3] = dblack[c]; + 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++) + mask[0][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); +// } + 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 (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; + /*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*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 != 32769 && tiff_compress != 32770) + || (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++) + romm_cam[0][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_off = 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[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) + 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_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++) + poff[0][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 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", 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 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 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 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 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 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 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 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 S200EXR", 512, 0x3fff, + { 11401,-4498,-1312,-5088,12751,2613,-838,1568,5941 } }, + { "Fujifilm S20Pro", 0, 0, + { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } }, + { "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 HS20EXR", 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 X100S", 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 X-Pro1", 0, 0, + { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, + { "Fujifilm X-E1", 0, 0, + { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, + { "Fujifilm XF1", 0, 0, + { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, + { "Fujifilm X-S1", 0, 0, + { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, + { "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 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 D4", 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 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 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 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 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", 0, 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 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 ", 0, 0, + { 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-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-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-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 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 ov5647", 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-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 645D", 0, 0x3e00, + { 10646,-3593,-1158,-3329,11699,1831,-667,2874,6287 } }, + { "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", 143, 0, + { 9938,-2780,-890,-4604,12393,2480,-1117,2304,4620 } }, + { "Panasonic DMC-FZ4", 143, 0, + { 13639,-5535,-1371,-1698,9633,2430,316,1152,4108 } }, + { "Panasonic DMC-FZ50", 0, 0, + { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } }, + { "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-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", 143, 0, + { 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } }, + { "Leica D-LUX 5", 143, 0, + { 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } }, + { "Panasonic DMC-LX7", 143, 0, + { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } }, + { "Leica D-LUX 6", 143, 0, + { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } }, + { "Panasonic DMC-FZ100", 143, 0xfff, + { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } }, + { "Leica V-LUX 2", 143, 0xfff, + { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } }, + { "Panasonic DMC-FZ150", 143, 0xfff, + { 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } }, + { "Leica V-LUX 3", 143, 0xfff, + { 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } }, + { "Panasonic DMC-FZ200", 143, 0xfff, + { 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } }, + { "Leica V-LUX 4", 143, 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", 143, 0xfff, + { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } }, + { "Panasonic DMC-G5", 143, 0xfff, + { 7798,-2562,-740,-3879,11584,2613,-1055,2248,5434 } }, + { "Panasonic DMC-G6", 143, 0xfff, /* DJC */ + { 6395,-2583,-40,-3677,9109,4569,-1502,2806,6431 } }, + { "Panasonic DMC-GF1", 15, 0xf92, + { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } }, + { "Panasonic DMC-GF2", 143, 0xfff, + { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } }, + { "Panasonic DMC-GF3", 143, 0xfff, + { 9051,-2468,-1204,-5212,13276,2121,-1197,2510,6890 } }, + { "Panasonic DMC-GF5", 143, 0xfff, + { 8228,-2945,-660,-3938,11792,2430,-1094,2278,5793 } }, + { "Panasonic DMC-GF6", 143, 0, + { 8130,-2801,-946,-3520,11289,2552,-1314,2511,5791 } }, + { "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", 144, 0, + { 6559,-1752,-491,-3672,11407,2586,-962,1875,5130 } }, + { "Panasonic DMC-GX1", 143, 0, + { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } }, + { "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 NX300", 0, 0, + { 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 NX", 0, 0, /* NX5, NX10, NX11, NX100 */ + { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } }, + { "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 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-RX100", 200, 0, + { 8651,-2754,-1057,-3464,12207,1373,-568,1398,4434 } }, + { "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-A5", 128, 0xfeb, + { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } }, + { "Sony DSLR-A700", 126, 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 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-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 (j=0; j < 12; j++) + cam_xyz[0][j] = table[i].trans[j] / 10000.0; + cam_xyz_coeff (cam_xyz); + } + break; + } + if (load_raw == &CLASS sony_arw2_load_raw) { // RT: arw2 scale fix + black <<= 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 (trans[0]) { + for (j=0; j < 12; j++) { + cam_xyz[0][j] = trans[j] / 10000.0; + } + cam_xyz_coeff (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[][6] = { + { 1944, 1416, 0, 0, 48, 0 }, + { 2144, 1560, 4, 8, 52, 2 }, + { 2224, 1456, 48, 6, 0, 2 }, + { 2376, 1728, 12, 6, 52, 2 }, + { 2672, 1968, 12, 6, 44, 2 }, + { 3152, 2068, 64, 12, 0, 0 }, + { 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 }, + { 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 }, + { 4312, 2876, 22, 18, 0, 2 }, + { 4352, 2874, 62, 18, 0, 0 }, + { 4476, 2954, 90, 34, 0, 0 }, + { 4480, 3348, 12, 10, 36, 12 }, + { 4496, 3366, 80, 50, 12, 0 }, + { 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 }, + { 5712, 3774, 62, 20, 10, 2 }, + { 5792, 3804, 158, 51, 0, 0 }, + { 5920, 3950, 122, 80, 2, 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" }, + { 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" }, + { 0x346, "EOS 100D" }, + }; + 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" }, + { 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, 8,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" }, + { 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","640x480" }, + { 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 }, + { 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" }, + { 614400, 640, 480, 0, 3, 0, 0,64,0x94,0,0,"Kodak","KAI-0340" }, + { 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","3072x2048",68 }, + { 33292868,4080,4080, 0, 0, 0, 0,33,0x61,0,0,"Sinar","4080x4080",68 }, + { 44390468,4080,5440, 0, 0, 0, 0,33,0x61,0,0,"Sinar","4080x5440",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_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,"\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"); + strcpy (model, "X2"); + order = 0x4949; + fseek (ifp, 300, SEEK_SET); + data_offset = get4(); + i = get4(); + width = get2(); + height = get2(); + data_offset += i - width * 5 / 4 * height; + load_raw = &CLASS nokia_load_raw; + 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; + } 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)) { + 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; + 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 == 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]; + } + 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 (!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); + 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[0][0] = top_margin = 16; + mask[0][2] = top_margin + height; + mask[0][3] = left_margin = 92; + } else if (!strcmp(model,"PowerShot SX50 HS")) { + mask[0][0] = top_margin = 17; + mask[0][2] = raw_height; + mask[0][3] = 80; + filters = 0x49494949; + } else if (!strcmp(model,"PowerShot G10")) { + filters = 0x49494949; + } 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") || + !strcmp(model,"D600") || + !strcmp(model,"D800") || !strcmp(model,"D800E") ) { + width -= 46; + } else if (!strcmp(model,"D4")) { + 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 (!strcmp(make,"Nikon") && raw_width == 4032) { + adobe_coeff ("Nikon","COOLPIX P7700"); + } else if (!strncmp(model,"COOLPIX P",9)) { + 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")) { + width += 2; + left_margin = 0; + filters = 0x16161616; + } + if (fuji_layout) raw_width *= is_raw; + } 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 -= 18; + width = 5536; + filters = 0x49494949; + } 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(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) { + height = 5502; + width = 7328; + 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; + } + } else if (!strcmp(make,"Sinar")) { + if (!load_raw) load_raw = &CLASS unpacked_load_raw; + 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 (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) { + adobe_coeff ("Sony","DSC-R1"); + width = 3925; + order = 0x4d4d; + } else if (!strcmp(make,"Sony") && raw_width == 5504) { + width -= 8; + } else if (!strcmp(make,"Sony") && raw_width == 6048) { + width -= 24; + } else if (!strcmp(model,"DSLR-A100")) { + if (width == 3880) { + height--; + width = ++raw_width; + } else { + 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")) { + order = 0x4949; + if (filters && data_offset) { + fseek (ifp, 168, SEEK_SET); + read_shorts (curve, 256); + } else gamma_curve (0, 3.875, 1, 255); + load_raw = filters ? &CLASS eight_bit_load_raw + : &CLASS kodak_yrgb_load_raw; + } 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)) { + width -= 4; + left_margin = 2; + } else if (!strcmp(model,"EOSDCS3B")) { + width -= 4; + left_margin = 2; + } else if (!strcmp(model,"EOSDCS1")) { + width -= 4; + left_margin = 2; + } else if (!strcmp(model,"DCS420")) { + width -= 4; + left_margin = 2; + } else if (!strncmp(model,"DCS460 ",7)) { + model[6] = 0; + width -= 4; + left_margin = 2; + } else if (!strcmp(model,"DCS460A")) { + width -= 4; + left_margin = 2; + colors = 1; + filters = 0; + } else if (!strcmp(model,"DCS660M")) { + black = 214; + colors = 1; + filters = 0; + } else if (!strcmp(model,"DCS760M")) { + 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 (raw_color) adobe_coeff (make, model); + if (load_raw == &CLASS kodak_radc_load_raw) + if (raw_color) adobe_coeff ("Apple","Quicktake"); + 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 (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 > 4 || 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; + + cmsErrorAction (LCMS_ERROR_SHOW); + 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: 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..9f6f17086 --- /dev/null +++ b/rtengine/dcraw.h @@ -0,0 +1,388 @@ +/* + * 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) + ,image(NULL) + ,bright(1.),threshold(0.) + ,half_size(0),four_color_rgb(0),document_mode(0),highlight(0) + ,verbose(0) + ,RT_whitelevel_from_constant(0) + ,RT_blacklevel_from_constant(0) + ,RT_matrix_from_constant(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) + ,getbithuff(this,ifp,zero_after_ff) + ,ph1_bithuff(this,ifp,order) + ,pana_bits(ifp,load_flags) + { + 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]; + 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; + 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[4], 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; + 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_matrix_from_constant; + int RT_blacklevel_from_constant; + int RT_whitelevel_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; + } tiff_ifd[10]; + + struct ph1 { + int format, key_off, black, black_off, split_col, tag_21a; + float tag_210; + } ph1; + + 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 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 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(); + +// 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_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 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 (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..46b4edb0e --- /dev/null +++ b/rtengine/dcraw.patch @@ -0,0 +1,1695 @@ +--- dcraw.c 2014-01-01 15:42:38 +0000 ++++ dcraw.cc 2014-01-01 18:32:58 +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-2013 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__) +@@ -98,87 +110,37 @@ + #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]; +-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, cblack[4], 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]; +-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, black, black_off, split_col, tag_21a; +- 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; } + + /* +@@ -254,6 +216,7 @@ + + if (filters == 1) return filter[(row+top_margin)&15][(col+left_margin)&15]; + if (filters == 9) return xtrans[(row+top_margin+6)%6][(col+left_margin+6)%6]; ++ + return FC(row,col); + } + +@@ -296,6 +259,7 @@ + fprintf (stderr,_("Corrupt data near 0x%llx\n"), (INT64) ftello(ifp)); + } + data_error++; ++/*RT*/ longjmp (failure, 1); + } + + ushort CLASS sget2 (uchar *s) +@@ -369,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 canon_600_fixed_wb (int temp) +@@ -541,10 +505,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; +@@ -1209,14 +1173,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() + { +@@ -1494,10 +1458,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) +@@ -1757,10 +1721,10 @@ + maximum = 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; +@@ -2049,11 +2013,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; +@@ -2373,10 +2337,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; +@@ -2386,8 +2349,10 @@ + for (p=0; p < 127; p++) + pad[p] = htonl(pad[p]); + } +- while (len--) +- *data++ ^= pad[p++ & 127] = pad[(p+1) & 127] ^ pad[(p+65) & 127]; ++ while (len--){ ++ *data++ ^= pad[p & 127] = pad[(p+1) & 127] ^ pad[(p+65) & 127]; ++ p++; ++ } + } + + void CLASS sony_load_raw() +@@ -2445,7 +2410,8 @@ + ushort pix[16]; + int row, col, val, max, min, imax, imin, sh, bit, i; + +- data = (uchar *) malloc (raw_width); ++ //data = (uchar *) malloc (raw_width); ++ data = (uchar *) malloc (raw_width + 1); // RT: added +1 to avoid buffer overrun + merror (data, "sony_arw2_load_raw()"); + for (row=0; row < height; row++) { + fread (data, 1, raw_width, ifp); +@@ -2464,11 +2430,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() +@@ -2690,7 +2658,7 @@ + + void CLASS foveon_decoder (unsigned size, unsigned code) + { +- static unsigned huff[1024]; ++/*RT static unsigned huff[1024];*/ + struct decode *cur; + int i, len; + +@@ -4003,239 +3971,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]) + { +@@ -4496,112 +4233,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() +@@ -4771,7 +4403,7 @@ + } + } + +-int CLASS parse_tiff_ifd (int base); ++/*RT int CLASS parse_tiff_ifd (int base);*/ + + void CLASS parse_makernote (int base, int uptag) + { +@@ -5177,7 +4809,7 @@ + { "","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 12" }; ++ "AFi-II 7","","","Aptus-II 6","","","Aptus-II 10","Aptus-II 5","","","","","Aptus-II 10R","Aptus-II 8","","Aptus-II 12","","AFi-II 12" }; // RT: added missing model names + float romm_cam[3][3]; + + fseek (ifp, offset, SEEK_SET); +@@ -5265,6 +4897,8 @@ + wbi = -2; + } + if (tag == 2118) wbtemp = getint(type); ++ if (tag == 2120 + wbi) /* RT: wb tag for DCS760 */ ++ FORC3 cam_mul[c] = 2048.0 / getreal(type); /* RT: wb tag for DCS760 */ + if (tag == 2130 + wbi) + FORC3 mul[c] = getreal(type); + if (tag == 2140 + wbi && wbi >= 0) +@@ -5284,8 +4918,8 @@ + } + } + +-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) + { +@@ -5299,7 +4933,7 @@ + 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; +@@ -5647,6 +5281,7 @@ + break; + case 61450: + blrr = blrc = 2; ++ if (filters == UINT_MAX) filters = 0x94949494; /* RT: Fuji X100 fix for dcraw 9.19 to get proper black level parsing, hopefully works for other Fuji cameras too! */ + case 50714: /* BlackLevel */ + black = getreal(type); + if ((unsigned)(filters+1) < 1000) break; +@@ -5737,12 +5372,13 @@ + 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); ++// } + ifp = sfp; + free (buf); + } +@@ -5766,6 +5402,7 @@ + int CLASS parse_tiff (int base) + { + int doff; ++ /*RT*/ if (exif_base == -1) exif_base = base; + + fseek (ifp, base, SEEK_SET); + order = get2(); +@@ -5843,7 +5480,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) && +@@ -5959,7 +5596,7 @@ + { + const char *file, *ext; + char *jname, *jfile, *jext; +- FILE *save=ifp; ++/*RT*/ IMFILE *save=ifp; + + ext = strrchr (ifname, '.'); + file = strrchr (ifname, '/'); +@@ -5981,13 +5618,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); +@@ -6330,7 +5968,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); + } +@@ -6582,7 +6224,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 } }, +@@ -7383,6 +7026,27 @@ + } + break; + } ++ if (load_raw == &CLASS sony_arw2_load_raw) { // RT: arw2 scale fix ++ black <<= 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 (trans[0]) { ++ for (j=0; j < 12; j++) { ++ cam_xyz[0][j] = trans[j] / 10000.0; ++ } ++ cam_xyz_coeff (cam_xyz); ++ } ++ } ++ } + } + + void CLASS simple_coeff (int index) +@@ -7682,13 +7346,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(); +@@ -7734,6 +7405,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); +@@ -7839,15 +7511,18 @@ + if (make[0] == 0) parse_smal (0, flen); + if (make[0] == 0) { + parse_jpeg(0); +- if (!strncmp(model,"ov",2) && !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; ++ //RT fix for the use of fseek below ++ if (!strncmp(model,"ov",2)) { ++ 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++) +@@ -7878,7 +7553,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")) +@@ -8026,7 +7701,7 @@ + width -= 44; + } else if (!strcmp(model,"D3200") || + !strcmp(model,"D600") || +- !strncmp(model,"D800",4)) { ++ !strcmp(model,"D800") || !strcmp(model,"D800E") ) { + width -= 46; + } else if (!strcmp(model,"D4")) { + width -= 52; +@@ -8631,194 +8306,7 @@ + } + #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; +-} ++/* RT: removed unused functions */ + + struct tiff_tag { + ushort tag, type; +@@ -8841,584 +8329,12 @@ + 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 + +-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 = (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 (use_camera_matrix < 0) +- use_camera_matrix = use_camera_wb; +- 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; +- } 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) { +- printf (_("\nFilter pattern: ")); +- for (i=0; i < 16; i++) +- putchar (cdesc[fcol(i >> 1,i & 1)]); +- } +- 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 (use_camera_matrix && cmatrix[0][0] > 0.25) { +- memcpy (rgb_cam, cmatrix, sizeof cmatrix); +- raw_color = 0; +- } +- 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; +- 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.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..778300230 --- /dev/null +++ b/rtengine/dcrop.cc @@ -0,0 +1,503 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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" +#include "colortemp.h" + +#define SKIPS(a,b) ((a) / (b) + ((a) % (b) > 0)) + +namespace rtengine { + +extern const Settings* settings; + +Crop::Crop (ImProcCoordinator* parent) + : origCrop(NULL), transCrop(NULL), laboCrop(NULL), labnCrop(NULL), + cropImg(NULL), cieCrop(NULL), cbuf_real(NULL), cshmap(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) +{ + parent->crops.push_back (this); +} + +Crop::~Crop () { + + MyMutex::MyLock cropLock(cropMutex); + MyMutex::MyLock processingLock(parent->mProcessing); + + std::vector::iterator i = std::find (parent->crops.begin(), parent->crops.end(), this); + if (i!=parent->crops.end ()) + parent->crops.erase (i); + freeAll (); +} + +void Crop::destroy () { + MyMutex::MyLock lock(cropMutex); + MyMutex::MyLock processingLock(parent->mProcessing); ///////// RETESTER MAINTENANT QUE CE VERROU EST AJOUTE!!! + 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; + } +} + +void Crop::update (int todo) { + MyMutex::MyLock lock(cropMutex); + + ProcParams& params = parent->params; + + // 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; + + bool needstransform = parent->ipf.needsTransform(); + + if (todo & (M_INIT|M_LINDENOISE)) { + MyMutex::MyLock lock(parent->minit); // Also used in improccoord + + int tr = TR_NONE; + if (params.coarse.rotate==90) tr |= TR_R90; + else if (params.coarse.rotate==180) tr |= TR_R180; + else if (params.coarse.rotate==270) tr |= TR_R270; + + if (params.coarse.hflip) tr |= TR_HFLIP; + if (params.coarse.vflip) tr |= TR_VFLIP; + + if (!needsinitupdate) + setCropSizes (rqcropx, rqcropy, rqcropw, rqcroph, skip, true); + PreviewProps pp (trafx, trafy, trafw*skip, trafh*skip, skip); + parent->imgsrc->getImage (parent->currWB, tr, origCrop, pp, params.toneCurve, params.icm, params.raw ); + //ColorTemp::CAT02 (origCrop, ¶ms) ; + + //parent->imgsrc->convertColorSpace(origCrop, params.icm); + + if (todo & M_LINDENOISE) { + if (skip==1 && params.dirpyrDenoise.enabled) + parent->ipf.RGB_denoise(origCrop, origCrop, parent->imgsrc->isRAW(), /*Roffset,*/ params.dirpyrDenoise, params.defringe, parent->imgsrc->getDirPyrDenoiseExpComp()); + } + parent->imgsrc->convertColorSpace(origCrop, params.icm, parent->currWB, params.raw); + } + + // 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; + cshmap->update (baseCrop, shradius, parent->ipf.lumimul, params.sh.hq, skip); + 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()); + }*/ + double rrm, ggm, bbm; + + if (todo & M_RGBCURVE) + parent->ipf.rgbProc (baseCrop, laboCrop, parent->hltonecurve, parent->shtonecurve, parent->tonecurve, cshmap, + params.toneCurve.saturation, parent->rCurve, parent->gCurve, parent->bCurve, parent->customToneCurve1, + parent->customToneCurve2, parent->beforeToneCurveBW, parent->afterToneCurveBW,rrm, ggm, bbm, + parent->bwAutoR, parent->bwAutoG, parent->bwAutoB); + + /*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; + + LUTu dummy; + parent->ipf.chromiLuminanceCurve (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); + parent->ipf.dirpyrequalizer (labnCrop); + } + } + + 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,(float**)cbuffer, execsharp, d); + } + 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,(float**)cbuffer, execsharp, dd); + } + } + else { + // CIECAM is disbaled, we free up its image buffer to save some space + if (cieCrop) delete cieCrop; cieCrop=NULL; + } + } + // 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; + if (params.icm.output=="" || params.icm.output==ColorManagementParams::NoICMString) outProfile="sRGB"; + Image8 *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; } + } + 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 = 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; + if (params.coarse.hflip) tr |= TR_HFLIP; + if (params.coarse.vflip) tr |= TR_VFLIP; + + 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) { + + freeAll (); + + cropw = cw; + croph = ch; + trafw = orW; + trafh = orH; + + origCrop = new Imagefloat (trafw, trafh); + //transCrop will be allocated later, if necessary + laboCrop = new LabImage (cropw, croph); + labnCrop = new LabImage (cropw, croph); + cropImg = new Image8 (cropw, croph); + //cieCrop is only used in Crop::update, it will be allocated on first use and deleted if not used anymore + 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 (); + } + parent->updaterThreadStart.unlock (); + + 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); +} + +} + diff --git a/rtengine/dcrop.h b/rtengine/dcrop.h new file mode 100644 index 000000000..52b6f9fe3 --- /dev/null +++ b/rtengine/dcrop.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 _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 "../rtgui/threadutils.h" + +namespace rtengine { + +using namespace procparams; + +class ImProcCoordinator; + +class Crop : public DetailedCrop { + + protected: + // --- permanently allocated in RAM and only renewed on size changes + Imagefloat* origCrop; // "one chunk" allocation + Imagefloat* transCrop; // "one chunk" allocation, allocated if necessary + LabImage* laboCrop; // "one chunk" allocation + LabImage* labnCrop; // "one chunk" allocation + Image8* cropImg; // "one chunk" allocation + CieImage* cieCrop; // allocating 6 images, each in "one chunk" allocation + float * cbuf_real; // "one chunk" allocation + SHMap* cshmap; // per line 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, upperBorder, leftBorder; + + bool cropAllocated; + DetailedCropListener* cropImageListener; + + MyMutex cropMutex; + ImProcCoordinator* parent; + + bool setCropSizes (int cx, int cy, int cw, int ch, int skip, bool internal); + void freeAll (); + + public: + Crop (ImProcCoordinator* parent); + virtual ~Crop (); + + 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;} +}; +} +#endif diff --git a/rtengine/demosaic_algos.cc b/rtengine/demosaic_algos.cc new file mode 100644 index 000000000..341f2905d --- /dev/null +++ b/rtengine/demosaic_algos.cc @@ -0,0 +1,3129 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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;} } +extern const Settings* settings; +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void RawImageSource::eahd_demosaic () { + if (plistener) { + plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::methodstring[RAWParams::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::methodstring[RAWParams::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 FORCC for (c=0; c < colors; c++) +#define fc(row,col) \ + (ri->prefilters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3) +typedef unsigned short ushort; +void RawImageSource::vng4_demosaic () { + static 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 }; + + if (plistener) { + plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::methodstring[RAWParams::vng4])); + plistener->setProgress (0.0); + } + + float (*brow[5])[4], *pix; + int prow=7, pcol=1, *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, width=W, height=H, colors=4; + float (*image)[4]; + int lcode[16][16][32], shift, i; + + image = (float (*)[4]) calloc (H*W, sizeof *image); + for (int ii=0; ii 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 /2); + memset (sum, 0, sizeof sum); + 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]]) /2; + 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] = 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]; + if (!(row%20) && plistener) + plistener->setProgress ((double)row / (H-2)); + } + 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]); + + for (int i=0; iget_filters() >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3) + +/* + 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::methodstring[RAWParams::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::methodstring[RAWParams::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::methodstring[RAWParams::lmmse])); + plistener->setProgress (0.0); + } + float (*image)[3]; + float maxdata=0.f; + image = (float (*)[3]) calloc (width*height, sizeof *image); + unsigned int a=0; +#ifdef _OPENMP +#pragma omp parallel for +#endif + for (int ii=0; iisetProgress (0.1); +} + +#ifdef _OPENMP +#pragma omp parallel firstprivate (image,rix,qix,h0,h1,h2,h3,h4) +#endif +{ +#ifdef _OPENMP +#pragma omp for +#endif + for (int rrr=0; rrr < rr1; rrr++) + for (int ccc=0, row=rrr-ba; ccc < cc1; ccc++) { + int col = ccc - ba; + rix = qix + rrr*cc1 + ccc; + if ((row >= 0) & (row < height) & (col >= 0) & (col < width)) { + if (applyGamma) + rix[0][4] = Color::gammatab_24_17a[image[row*width+col][FC(row,col)]]; + else + rix[0][4] = (float)image[row*width+col][FC(row,col)]/65535.0f; + } + else + rix[0][4] = 0.f; + } +#ifdef _OPENMP +#pragma omp single +#endif +{ + if (plistener) plistener->setProgress (0.2); +} + + + // G-R(B) +#ifdef _OPENMP +#pragma omp for +#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 = qix + rr*cc1 + cc; + float v0 = x00625(rix[-w1-1][4]+rix[-w1+1][4]+rix[w1-1][4]+rix[w1+1][4]) +x0250(rix[0][4]); + // horizontal + rix[0][0] = - x0250(rix[ -2][4] + rix[ 2][4])+ xdiv2f(rix[ -1][4] + rix[0][4] + rix[ 1][4]); + float Y = v0 + xdiv2f(rix[0][0]); + if (rix[0][4] > 1.75f*Y) + rix[0][0] = ULIM(rix[0][0],rix[ -1][4],rix[ 1][4]); + else + rix[0][0] = LIM(rix[0][0],0.0f,1.0f); + rix[0][0] -= rix[0][4]; + // vertical + rix[0][1] = -x0250(rix[-w2][4] + rix[w2][4])+ xdiv2f(rix[-w1][4] + rix[0][4] + rix[w1][4]); + Y = v0 + xdiv2f(rix[0][1]); + if (rix[0][4] > 1.75f*Y) + rix[0][1] = ULIM(rix[0][1],rix[-w1][4],rix[w1][4]); + else + rix[0][1] = LIM(rix[0][1],0.0f,1.0f); + rix[0][1] -= rix[0][4]; + } + // G-R(B) at G location + for (int ccc=2+(FC(rr,3)&1); ccc < cc1-2; ccc+=2) { + rix = qix + rr*cc1 + ccc; + rix[0][0] = x0250(rix[ -2][4] + rix[ 2][4])- xdiv2f(rix[ -1][4] + rix[0][4] + rix[ 1][4]); + rix[0][1] = x0250(rix[-w2][4] + rix[w2][4])- xdiv2f(rix[-w1][4] + rix[0][4] + rix[w1][4]); + rix[0][0] = LIM(rix[0][0],-1.0f,0.0f) + rix[0][4]; + rix[0][1] = LIM(rix[0][1],-1.0f,0.0f) + rix[0][4]; + } + } +#ifdef _OPENMP +#pragma omp single +#endif +{ + if (plistener) plistener->setProgress (0.25); +} + + + // 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 = qix + rr*cc1 + cc; + rix[0][2] = h0*rix[0][0] + h1*(rix[ -1][0] + rix[ 1][0]) + h2*(rix[ -2][0] + rix[ 2][0]) + h3*(rix[ -3][0] + rix[ 3][0]) + h4*(rix[ -4][0] + rix[ 4][0]); + rix[0][3] = h0*rix[0][1] + h1*(rix[-w1][1] + rix[w1][1]) + h2*(rix[-w2][1] + rix[w2][1]) + h3*(rix[-w3][1] + rix[w3][1]) + h4*(rix[-w4][1] + rix[w4][1]); + } +#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++) + for (int cc=4+(FC(rr,4)&1); cc < cc1-4; cc+=2) { + rix = qix + rr*cc1 + cc; + // horizontal + float mu = (rix[-4][2] + rix[-3][2] + rix[-2][2] + rix[-1][2] + rix[0][2]+ rix[ 1][2] + rix[ 2][2] + rix[ 3][2] + rix[ 4][2]) / 9.0f; + float p1 = rix[-4][2] - mu; + float p2 = rix[-3][2] - mu; + float p3 = rix[-2][2] - mu; + float p4 = rix[-1][2] - mu; + float p5 = rix[ 0][2] - mu; + float p6 = rix[ 1][2] - mu; + float p7 = rix[ 2][2] - mu; + float p8 = rix[ 3][2] - mu; + float p9 = rix[ 4][2] - mu; + float vx = 1e-7+p1*p1+p2*p2+p3*p3+p4*p4+p5*p5+p6*p6+p7*p7+p8*p8+p9*p9; + p1 = rix[-4][0] - rix[-4][2]; + p2 = rix[-3][0] - rix[-3][2]; + p3 = rix[-2][0] - rix[-2][2]; + p4 = rix[-1][0] - rix[-1][2]; + p5 = rix[ 0][0] - rix[ 0][2]; + p6 = rix[ 1][0] - rix[ 1][2]; + p7 = rix[ 2][0] - rix[ 2][2]; + p8 = rix[ 3][0] - rix[ 3][2]; + p9 = rix[ 4][0] - rix[ 4][2]; + float vn = 1e-7+p1*p1+p2*p2+p3*p3+p4*p4+p5*p5+p6*p6+p7*p7+p8*p8+p9*p9; + float xh = (rix[0][0]*vx + rix[0][2]*vn)/(vx + vn); + float vh = vx*vn/(vx + vn); + // vertical + mu = (rix[-w4][3] + rix[-w3][3] + rix[-w2][3] + rix[-w1][3] + rix[0][3]+rix[ w1][3] + rix[ w2][3] + rix[ w3][3] + rix[ w4][3]) / 9.0f; + p1 = rix[-w4][3] - mu; + p2 = rix[-w3][3] - mu; + p3 = rix[-w2][3] - mu; + p4 = rix[-w1][3] - mu; + p5 = rix[ 0][3] - mu; + p6 = rix[ w1][3] - mu; + p7 = rix[ w2][3] - mu; + p8 = rix[ w3][3] - mu; + p9 = rix[ w4][3] - mu; + vx = 1e-7+p1*p1+p2*p2+p3*p3+p4*p4+p5*p5+p6*p6+p7*p7+p8*p8+p9*p9; + p1 = rix[-w4][1] - rix[-w4][3]; + p2 = rix[-w3][1] - rix[-w3][3]; + p3 = rix[-w2][1] - rix[-w2][3]; + p4 = rix[-w1][1] - rix[-w1][3]; + p5 = rix[ 0][1] - rix[ 0][3]; + p6 = rix[ w1][1] - rix[ w1][3]; + p7 = rix[ w2][1] - rix[ w2][3]; + p8 = rix[ w3][1] - rix[ w3][3]; + p9 = rix[ w4][1] - rix[ w4][3]; + vn = 1e-7+p1*p1+p2*p2+p3*p3+p4*p4+p5*p5+p6*p6+p7*p7+p8*p8+p9*p9; + float xv = (rix[0][1]*vx + rix[0][3]*vn)/(vx + vn); + float vv = vx*vn/(vx + vn); + // interpolated G-R(B) + rix[0][4] = (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; + rix = qix + rr*cc1 + cc; + int c = FC(rr,cc); + if ((row >= 0) & (row < height) & (col >= 0) & (col < width)) { + if (applyGamma) + rix[0][c] = Color::gammatab_24_17a[image[row*width+col][c]]; + else + rix[0][c] = (float)image[row*width+col][c]/65535.0f; + } + else + rix[0][c] = 0.f; + if (c != 1) rix[0][1] = rix[0][c] + rix[0][4]; + } +#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 = qix + rr*cc1 + cc; + rix[0][c] = rix[0][1] + xdiv2f(rix[ -1][c] - rix[ -1][1] + rix[ 1][c] - rix[ 1][1]); + c = 2 - c; + rix[0][c] = rix[0][1]+ xdiv2f(rix[-w1][c] - rix[-w1][1] + rix[w1][c] - rix[w1][1]); + 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 = qix + rr*cc1 + cc; + rix[0][c] = rix[0][1]+ x0250(rix[-w1][c] - rix[-w1][1] + rix[ -1][c] - rix[ -1][1]+ rix[ 1][c] - rix[ 1][1] + rix[ w1][c] - rix[ w1][1]); + } +#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++) { + for (int c=0; c < 3; c+=2) { + // Compute median(R-G) and median(B-G) + int d = c + 3; + for (int ii=0; ii < rr1*cc1; ii++) qix[ii][d] = qix[ii][c] - qix[ii][1]; + // Apply 3x3 median filter +#ifdef _OPENMP +#pragma omp parallel for firstprivate (rix,qix) +#endif + for (int rr=1; rr < rr1-1; rr++) + for (int cc=1; cc < cc1-1; cc++) { + float temp; + rix = qix + rr*cc1 + cc; + // Assign 3x3 differential color values + float p1 = rix[-w1-1][d]; float p2 = rix[-w1][d]; float p3 = rix[-w1+1][d]; + float p4 = rix[ -1][d]; float p5 = rix[ 0][d]; float p6 = rix[ 1][d]; + float p7 = rix[ w1-1][d]; float p8 = rix[ w1][d]; float p9 = rix[ w1+1][d]; + // 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[0][4] = p5; + } + for (int ii=0; ii < rr1*cc1; ii++) qix[ii][d] = qix[ii][4]; + } + // red/blue at GREEN pixel locations + for (int rr=0; rr < rr1; rr++) + for (int cc=(FC(rr,1)&1) /*, c=FC(rr,cc+1)*/; cc < cc1; cc+=2) { + rix = qix + rr*cc1 + cc; + rix[0][0] = rix[0][1] + rix[0][3]; + rix[0][2] = rix[0][1] + rix[0][5]; + } + // red/blue and green at BLUE/RED pixel locations + for (int rr=0; rr < rr1; rr++) + for (int cc=(FC(rr,0)&1), c=2-FC(rr,cc),d=c+3; cc < cc1; cc+=2) { + rix = qix + rr*cc1 + cc; + rix[0][c] = rix[0][1] + rix[0][d]; + rix[0][1] = xdiv2f(rix[0][0] - rix[0][3] + rix[0][2] - rix[0][5]); + } + } + + if (plistener) plistener->setProgress (0.8); +#ifdef _OPENMP +#pragma omp parallel firstprivate (image,rix,qix) +#endif +{ + // copy result back to image matrix +#ifdef _OPENMP +#pragma omp for +#endif + for (int row=0; row < height; row++) + for (int col=0, rr=row+ba; col < width; col++) { + int cc = col+ba; + rix = qix + rr*cc1 + cc; + int c = FC(row,col); + float v0; + + if (applyGamma) { + for (int ii=0; ii < 3; ii++) + if (ii != c) { + v0 = 65535.f*rix[0][ii]; + image[row*width+col][ii]=Color::igammatab_24_17[v0]; + } + } + else + for (int ii=0; ii < 3; ii++) + if (ii != c) + image[row*width+col][ii] = ((65535.0f*rix[0][ii] + 0.5f)); + } +#ifdef _OPENMP +#pragma omp for +#endif + for (int ii=0; iisetProgress (1.0); + free(buffer); + free(image); + //if(iterations > 4) refinement_lassus(passref); + 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::methodstring[RAWParams::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::methodstring[RAWParams::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::methodstring[RAWParams::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; 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=2; row < height-2; row++) + for (int col=2+(FC(row,2) & 1), c=FC(row,col); col < width-2; col+=2) { + int indx = row*width+col; + float (*pix)[3]= image + indx; + double dL = 1.0/(1.0+fabs(pix[ -2][c]-pix[0][c])+fabs(pix[ 1][1]-pix[ -1][1])); + double dR = 1.0/(1.0+fabs(pix[ 2][c]-pix[0][c])+fabs(pix[ 1][1]-pix[ -1][1])); + double dU = 1.0/(1.0+fabs(pix[-w2][c]-pix[0][c])+fabs(pix[w1][1]-pix[-w1][1])); + double dD = 1.0/(1.0+fabs(pix[ w2][c]-pix[0][c])+fabs(pix[w1][1]-pix[-w1][1])); + float v0 = (float)((double)pix[0][c] + 0.5 +((double)(pix[ -1][1]-pix[ -1][c])*dL +(double)(pix[ 1][1]-pix[ 1][c])*dR +(double)(pix[-w1][1]-pix[-w1][c])*dU + + (double)(pix[ w1][1]-pix[ w1][c])*dD ) / (dL+dR+dU+dD)); + pix[0][1] = 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++) + for (int col=2+(FC(row,3) & 1), c=FC(row,col+1); col < width-2; col+=2) { + int indx = row*width+col; + float (*pix)[3] = image + indx; + for (int i=0; i < 2; c=2-c, i++) { + double dL = 1.0/(1.0+fabs(pix[ -2][1]-pix[0][1])+fabs(pix[ 1][c]-pix[ -1][c])); + double dR = 1.0/(1.0+fabs(pix[ 2][1]-pix[0][1])+fabs(pix[ 1][c]-pix[ -1][c])); + double dU = 1.0/(1.0+fabs(pix[-w2][1]-pix[0][1])+fabs(pix[w1][c]-pix[-w1][c])); + double dD = 1.0/(1.0+fabs(pix[ w2][1]-pix[0][1])+fabs(pix[w1][c]-pix[-w1][c])); + float v0 = (float)((double)pix[0][1] + 0.5 -((double)(pix[ -1][1]-pix[ -1][c])*dL + (double)(pix[ 1][1]-pix[ 1][c])*dR +(double)(pix[-w1][1]-pix[-w1][c])*dU + + (double)(pix[ w1][1]-pix[ w1][c])*dD ) / (dL+dR+dU+dD)); + pix[0][c] = 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++) + for (int col=2+(FC(row,2) & 1), c=2-FC(row,col); col < width-2; col+=2) { + int indx = row*width+col; + float (*pix)[3] = image + indx; + int d = 2 - c; + double dL = 1.0/(1.0+ABS(pix[ -2][d]-pix[0][d])+ABS(pix[ 1][1]-pix[ -1][1])); + double dR = 1.0/(1.0+ABS(pix[ 2][d]-pix[0][d])+ABS(pix[ 1][1]-pix[ -1][1])); + double dU = 1.0/(1.0+ABS(pix[-w2][d]-pix[0][d])+ABS(pix[w1][1]-pix[-w1][1])); + double dD = 1.0/(1.0+ABS(pix[ w2][d]-pix[0][d])+ABS(pix[w1][1]-pix[-w1][1])); + float v0 = (float)((double)pix[0][1] + 0.5 -((double)(pix[ -1][1]-pix[ -1][c])*dL +(double)(pix[ 1][1]-pix[ 1][c])*dR +(double)(pix[-w1][1]-pix[-w1][c])*dU + + (double)(pix[ w1][1]-pix[ w1][c])*dD ) / (dL+dR+dU+dD)); + pix[0][c] = CLIP(v0); + } +} + +#ifdef _OPENMP +#pragma omp for +#endif + for (int i=0;iverbose) printf("Refinement Lee %d usec\n", t2e.etime(t1e)); +} + + +// 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::methodstring[RAWParams::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); +} +#undef TILEBORDER +#undef TILESIZE +#undef CACHESIZE +} /* namespace */ diff --git a/rtengine/dfmanager.cc b/rtengine/dfmanager.cc new file mode 100644 index 000000000..1a13812cc --- /dev/null +++ b/rtengine/dfmanager.cc @@ -0,0 +1,447 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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" + +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::list& 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->isBayer()?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->isBayer() ){ + 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 int threshold=10; + if( df->isBayer() ){ + for( int row=2; rowget_height()-2; row++) + for( int col=2; col < df->get_width()-2; col++){ + int 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])/8; + if( df->data[row][col]/threshold > m ) + badPixels.push_back( badPix(col,row) ); + } + }else{ + for( int row=1; rowget_height()-1; row++) + for( int col=1; col < df->get_width()-1; col++){ + int 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])/8; + } + if( df->data[row][3*col]/threshold > m[0] || df->data[row][3*col+1]/threshold > m[1] || df->data[row][3*col+2]/threshold > m[2]) + 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(idata.getMake(), idata.getModel(),idata.getISOSpeed(),idata.getShutterSpeed()) ); + iter = dfList.find( key ); + if( iter == dfList.end() ){ + dfInfo n(filename, idata.getMake(), idata.getModel(),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, idata.getMake(), idata.getModel(),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( mak, mod, 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::list *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::list *DFManager::getHotPixels ( const std::string &mak, const std::string &mod, int iso, double shut, time_t t ) +{ + dfInfo *df = find( mak, mod, 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::list bp; + char line[256]; + while( fgets(line,sizeof(line),file ) ){ + int x,y; + if( sscanf(line,"%d %d",&x,&y) == 2 ) + bp.push_back( badPix(x,y) ); + } + int numPixels = bp.size(); + if( numPixels >0 ) + bpList[ makmodel ] = bp; + fclose(file); + return numPixels; +} + +std::list *DFManager::getBadPixels ( const std::string &mak, const std::string &mod, const std::string &serial) +{ + std::ostringstream s; + s << mak << " " <verbose ) + printf("Found:%s.badpixels in list\n",s.str().c_str()); + return &(iter->second); + } + if( settings->verbose ) + printf("%s.badpixels not found\n",s.str().c_str()); + return 0; +} + +// Global variable +DFManager dfm; + + +} + diff --git a/rtengine/dfmanager.h b/rtengine/dfmanager.h new file mode 100644 index 000000000..3a171b714 --- /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::list &getHotPixels(); + +protected: + RawImage *ri; ///< Dark Frame raw data + std::list 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::list *getHotPixels ( const std::string &mak, const std::string &mod, int iso, double shut, time_t t ); + std::list *getHotPixels ( const Glib::ustring filename ); + std::list *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..fe816b736 --- /dev/null +++ b/rtengine/diagonalcurves.cc @@ -0,0 +1,324 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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]; + for (int i=0; i<4; i++) + x[i] = p[i]; + 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 = 0; + unsigned int k_hi = 0; + + 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..0b26723f8 --- /dev/null +++ b/rtengine/dirpyr_equalizer.cc @@ -0,0 +1,430 @@ +/* + * 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 "array2D.h" +#include "rt_math.h" +#ifdef __SSE2__ +#include "sleefsseavx.c" +#endif +#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 = 5; + static const float noise = 2000; + static const float thresh = 1000; + + //sequence of scales + static const int scales[8] = {1,2,4,8,16,32,64,128}; + + //sequence of scales + //static const int scales[8] = {1,2,3,6,15,21,28,36}; + //scale is spacing of directional averaging weights + + + void ImProcFunctions :: dirpyr_equalizer(float ** src, float ** dst, int srcwidth, int srcheight, const double * mult, const double dirpyrThreshold ) + { + int lastlevel=maxlevel; + + 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; + + multi_array2D dirpyrlo (srcwidth, srcheight); + + level = 0; + + int scale = scales[level]; + //int thresh = 100 * mult[5]; + + dirpyr_channel(src, dirpyrlo[0], srcwidth, srcheight, 0, scale ); + + level = 1; + + while(level < lastlevel) + { + scale = scales[level]; + + 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_channel(dirpyrlo[level], dirpyrlo[level-1], buffer, srcwidth, srcheight, level, mult, dirpyrThreshold ); + } + + + scale = scales[0]; + + idirpyr_eq_channel(dirpyrlo[0], dst, buffer, srcwidth, srcheight, 0, mult, dirpyrThreshold ); + + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + for (int i=0; i0) { + lastlevel--; + //printf("last level to process %d \n",lastlevel); + } + if (lastlevel==0) return; + + int level; + + multi_array2D dirpyrlo (srcwidth, srcheight); + + level = 0; + + int scale = scales[level]; + //int thresh = 100 * mult[5]; + + dirpyr_channel(src, dirpyrlo[0], srcwidth, srcheight, 0, scale ); + + level = 1; + + while(level < lastlevel) + { + scale = scales[level]; + + 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_channel(dirpyrlo[level], dirpyrlo[level-1], buffer, srcwidth, srcheight, level, mult, dirpyrThreshold ); + } + + + scale = scales[0]; + + idirpyr_eq_channel(dirpyrlo[0], dst, buffer, srcwidth, srcheight, 0, mult, dirpyrThreshold ); + + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + if(execdir) +#ifdef _OPENMP +#pragma omp parallel for +#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}}; + halfwin=2; + scalewin = halfwin*scale; +#ifdef _OPENMP +#pragma omp parallel +#endif +{ +#ifdef __SSE2__ + __m128 thousandv = _mm_set1_ps( 1000.0f ); + __m128 dirwtv, valv, normv; + float domkerv[5][5][4] = {{{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}},{{1,1,1,1},{2,2,2,2},{2,2,2,2},{2,2,2,2},{1,1,1,1}},{{1,1,1,1},{2,2,2,2},{2,2,2,2},{2,2,2,2},{1,1,1,1}},{{1,1,1,1},{2,2,2,2},{2,2,2,2},{2,2,2,2},{1,1,1,1}},{{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}}}; +#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; + float norm=0; + + 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) { + 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(); + + 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) { + dirwtv = _mm_loadu_ps((float*)&domkerv[(inbr-i)/scale+halfwin][(jnbr-j)/scale+halfwin]) * (thousandv / (vabsf(LVFU(data_fine[inbr][jnbr])-(LVFU(data_fine[i][j]))) + thousandv)); + valv += dirwtv*LVFU(data_fine[inbr][jnbr]); + normv += dirwtv; + } + } + _mm_storeu_ps( &data_coarse[i][j],valv/normv);//low pass filter + } + for(; j < width-scalewin; j++) + { + float val=0; + float norm=0; + + 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; + float norm=0; + + 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; + float norm=0; + + 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 + halfwin = 1; + scalewin = halfwin*scale; +#ifdef _OPENMP +#pragma omp parallel +#endif +{ +#ifdef __SSE2__ + __m128 thousandv = _mm_set1_ps( 1000.0f ); + __m128 dirwtv, valv, normv; +#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; + float norm=0; + + 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) { + 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-scalewin-3; j+=4) + { + valv = _mm_setzero_ps(); + normv = _mm_setzero_ps(); + + 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) { + dirwtv = thousandv / (vabsf(LVFU(data_fine[inbr][jnbr])-(LVFU(data_fine[i][j]))) + thousandv); + valv += dirwtv*LVFU(data_fine[inbr][jnbr]); + normv += dirwtv; + } + } + _mm_storeu_ps( &data_coarse[i][j], valv/normv);//low pass filter + } + + for(; j < width-scalewin; j++) + { + float val=0; + float norm=0; + + 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 = 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-scalewin; j++) + { + float val=0; + float norm=0; + + 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 = 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; + float norm=0; + + 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 = 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, const double * mult, const double dirpyrThreshold ) + { + float noisehi = 1.33*noise*dirpyrThreshold/expf(level*log(3.0)), noiselo = 0.66*noise*dirpyrThreshold/expf(level*log(3.0)); + LUTf irangefn (0x20000); + + for (int i=0; i<0x20000; i++) { + if (abs(i-0x10000)>noisehi || mult[level]<1.0) { + irangefn[i] = mult[level] ; + } else { + if (abs(i-0x10000) + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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..6dfe33665 --- /dev/null +++ b/rtengine/expo_before_b.cc @@ -0,0 +1,164 @@ + +//////////////////////////////////////////////////////////////// +// +// //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) +// +// 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" +#include "../rtgui/options.h" + +namespace rtengine { + +extern const Settings* settings; + +void RawImageSource::processRawWhitepoint(float expos, float preser) { + MyTime t1e,t2e; + t1e.set(); + + int width=W, height=H; + + // exposure correction inspired from G.Luijk + if (fabs(preser)<0.001) { + // No highlight protection - simple mutiplication + for (int c=0; c<4; c++) chmax[c] *= expos; + + #pragma omp parallel for + for (int row=0;rowisBayer()) { + rawData[row][col] *= expos; + } else { + rawData[row][col*3] *= expos; + rawData[row][col*3+1] *= expos; + rawData[row][col*3+2] *= expos; + } + } + } else { + // calculate CIE luminosity + float* luminosity = (float *) new float[width*height]; + + if (ri->isBayer()) { + // save old image as it's overwritten by demosaic + float** imgd = allocArray< float >(W,H); + + // with memcpy it's faster than for (...) + for (int i=0; i(imgd, H); + } else { + // Non-Bayers are already RGB + + // CIE luminosity + #pragma omp parallel for + for(int row=0;rowisBayer()) { + if (rawData[row][col]>maxVal) maxVal = rawData[row][col]; + } else { + for (int c=0;c<3;c++) if (rawData[row][col*3+c]>maxVal) maxVal = rawData[row][col*3+c]; + } + } + + // Exposure correction with highlight preservation + LUTf lut(maxVal+1); + if(expos>1){ + // Positive exposure + + float K = (float) maxVal / expos*exp(-preser*log(2.0)); + for (int j=0;j<=maxVal;j++) + lut[(int)j]=(((float)maxVal-K*expos)/((float)maxVal-K)*(j-maxVal)+(float) maxVal) / j; + + for (int c=0; c<4; c++) chmax[c] *= expos; + + #pragma omp parallel for + for(int row=0;rowisBayer()) { + rawData[row][col] *= fac; + } else { + for (int c=0;c<3;c++) rawData[row][col*3+c] *= fac; + } + } + } else { + // Negative exposure + float EV=log(expos)/log(2.0); // Convert exp. linear to EV + float 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)); + + #pragma omp parallel for + for(int row=0;rowisBayer()) { + rawData[row][col] *= fac; + } else { + for (int c=0;c<3;c++) rawData[row][col*3+c] *= fac; + } + } + + for (int c=0; c<4; c++) chmax[c] *= expos; + } + + delete[] luminosity; + } + t2e.set(); + if (settings->verbose) + 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..2b1abe526 --- /dev/null +++ b/rtengine/fast_demo.cc @@ -0,0 +1,284 @@ +//////////////////////////////////////////////////////////////// +// +// 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" + +/*#ifdef _OPENMP +#include +#endif*/ + +using namespace std; +using namespace rtengine; + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +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; +} + +LUTf RawImageSource::invGrad = RawImageSource::initInvGrad(); + +void RawImageSource::fast_demosaic(int winx, int winy, int winw, int winh) { + //int winx=0, winy=0; + //int winw=W, winh=H; + + if (plistener) { + plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::methodstring[RAWParams::fast])); + plistener->setProgress (0.0); + } + float progress = 0.0; + + + const int bord=4; + + int clip_pt = 4*65535*initialGain; + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +#ifdef _OPENMP +#pragma omp parallel +#endif + { +#ifdef _OPENMP +#pragma omp for +#endif + //first, interpolate borders using bilinear + for (int i=0; i -1) && (i1 < H) && (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=W-bord; j -1) && (i1 < H ) && (j1 < W)) { + 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 + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +#ifdef _OPENMP +#pragma omp for +#endif + for (int j=bord; j -1) && (j1 < W) && (i1 > -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]; + } + } + }//i + + for (int i=H-bord; i -1) && (j1 < W) && (i1 < H)) { + 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]; + } + } + }//i + }//j + + if(plistener) plistener->setProgress(0.05); + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +#ifdef _OPENMP +#pragma omp for +#endif + // interpolate G using gradient weights + for (int i=bord; i< H-bord; i++) { + float wtu, wtd, wtl, wtr; + for (int j=bord; j < W-bord; j++) { + + if (FC(i,j)==1) { + green[i][j] = rawData[i][j]; + //red[i][j] = green[i][j]; + //blue[i][j] = green[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])) /4]; + 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])) /4]; + 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])) /4]; + 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])) /4]; + + //store in rgb array the interpolated G value at R/B grid points using directional weighted average + green[i][j]=(wtu*rawData[i-1][j]+wtd*rawData[i+1][j]+wtl*rawData[i][j-1]+wtr*rawData[i][j+1]) / (wtu+wtd+wtl+wtr); + //red[i][j] = green[i][j]; + //blue[i][j] = green[i][j]; + + } + } + //progress+=(double)0.33/(H); + //if(plistener) plistener->setProgress(progress); + } + if(plistener) plistener->setProgress(0.4); + +#ifdef _OPENMP +#pragma omp for +#endif + for (int i=bord; i< H-bord; i++) { + for (int j=bord+(FC(i,2)&1); j < W-bord; j+=2) { + + int c=FC(i,j); + //interpolate B/R colors at R/B sites + + if (c==0) {//R site + red[i][j] = rawData[i][j]; + blue[i][j] = green[i][j] - 0.25f*((green[i-1][j-1]+green[i-1][j+1]+green[i+1][j+1]+green[i+1][j-1]) - + min(static_cast(clip_pt),rawData[i-1][j-1]+rawData[i-1][j+1]+rawData[i+1][j+1]+rawData[i+1][j-1])); + } else {//B site + red[i][j] = green[i][j] - 0.25f*((green[i-1][j-1]+green[i-1][j+1]+green[i+1][j+1]+green[i+1][j-1]) - + min(static_cast(clip_pt),rawData[i-1][j-1]+rawData[i-1][j+1]+rawData[i+1][j+1]+rawData[i+1][j-1])); + blue[i][j] = rawData[i][j]; + } + } + //progress+=(double)0.33/(H); + //if(plistener) plistener->setProgress(progress); + } + if(plistener) plistener->setProgress(0.7); + +#ifdef _OPENMP +#pragma omp barrier +#endif + +#ifdef _OPENMP +#pragma omp for +#endif + + // interpolate R/B using color differences + for (int i=bord; i< H-bord; i++) { + for (int j=bord+1-(FC(i,2)&1); j < W-bord; j+=2) { + + //interpolate R and B colors at G sites + red[i][j] = green[i][j] - 0.25f*((green[i-1][j]-red[i-1][j])+(green[i+1][j]-red[i+1][j])+ + (green[i][j-1]-red[i][j-1])+(green[i][j+1]-red[i][j+1])); + blue[i][j] = green[i][j] - 0.25f*((green[i-1][j]-blue[i-1][j])+(green[i+1][j]-blue[i+1][j])+ + (green[i][j-1]-blue[i][j-1])+(green[i][j+1]-blue[i][j+1])); + } + progress+=(double)0.33/(H); + //if(plistener) plistener->setProgress(progress); + } + if(plistener) plistener->setProgress(0.99); + } // End of parallelization + +#undef bord + +} diff --git a/rtengine/ffmanager.cc b/rtengine/ffmanager.cc new file mode 100644 index 000000000..f888c5983 --- /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 "../rtgui/guiutils.h" +#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->isBayer()?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->isBayer() ){ + 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..3236b57d1 --- /dev/null +++ b/rtengine/flatcurves.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 +#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]; + } + else { + N--; + } + if (!identity && N > 0+(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) + kind = FCT_Empty; + else + kind = FCT_MinMaxCPoints; + + return kind==FCT_Empty; +} + +void FlatCurve::CtrlPoints_set () { + + 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 periodic=%d nbr_points=%d ppn=%d N=%d sc_length[i/3]=%f total_length=%f",i,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 : { + /* To be updated if we have to handle non periodic flat curves + // values under and over the first and last point + if (t>x[N-1]) + return y[N-1]; + else if (t 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..6e4d352bb --- /dev/null +++ b/rtengine/helpersse2.h @@ -0,0 +1,249 @@ +#ifndef __SSE2__ +#error Please specify -msse2. +#endif + +#ifdef __GNUC__ +#define INLINE __inline +//#define INLINE __attribute__((always_inline)) +#else +#define INLINE inline +#endif + +#if defined( WIN32 ) && defined(__x86_64__) + #include +#else + #include +#endif + +#include + +typedef __m128d vdouble; +typedef __m128i vint; +typedef __m128i vmask; + +typedef __m128 vfloat; +typedef __m128i vint2; + +// +#define LVF(x) _mm_load_ps(&x) +#define LVFU(x) _mm_loadu_ps(&x) +#define LC2VFU(a) _mm_shuffle_ps( LVFU(a), _mm_loadu_ps( (&a) + 4 ), _MM_SHUFFLE( 2,0,2,0 ) ) +#define ZEROV _mm_setzero_ps() + +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 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..67e0a3028 --- /dev/null +++ b/rtengine/hilite_recon.cc @@ -0,0 +1,859 @@ +//////////////////////////////////////////////////////////////// +// +// 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 "rtengine.h" +#include +#include +#include "curves.h" +#include "array2D.h" +#include "improcfun.h" +#include "rawimagesource.h" +//#include "stack1.h" + + +#ifdef _OPENMP +#include +#endif + +#include "rt_math.h" +#include "rawimagesource.h" +#ifdef __SSE2__ +#include "sleefsseavx.c" +#endif // __SSE2__ + + + + +#define FOREACHCOLOR for (int c=0; c < ColorCount; c++) + +//#include "RGBdefringe.cc" + +namespace rtengine { + + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +#if defined( __SSE2__ ) && defined( WIN32 ) +__attribute__((force_align_arg_pointer)) void RawImageSource::boxblur2(float** src, float** dst, int H, int W, int box ) +#else +void RawImageSource::boxblur2(float** src, float** dst, int H, int W, int box ) +#endif +{ + + 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); + + float maxtmp=0.0f; + +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + float maxtmpthr = 0; + 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; + maxtmpthr = max(maxtmpthr,src[row][0]); + for (int j=1; j<=box; j++) { + tempval += src[row][j]/len; + maxtmpthr = max(maxtmpthr,src[row][j]); + } + 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; + maxtmpthr = max(maxtmpthr,src[row][col]); + 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; + maxtmpthr = max(maxtmpthr,src[row][col]); + } + 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) +#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 +#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],chmaxalt[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 +#ifdef _OPENMP +#pragma omp parallel for +#endif + 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); + } + +#ifdef _OPENMP +#pragma omp parallel for +#endif + 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); + } + +#ifdef _OPENMP +#pragma omp parallel for +#endif + 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); + } + +#ifdef _OPENMP +#pragma omp parallel for +#endif + 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); + } + +#ifdef _OPENMP +#pragma omp parallel for +#endif + //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 +#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); + } + } + 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->isBayer()) && red[j] > maxr) maxr = red[j]; + if ((ri->ISGREEN(i,j) || !ri->isBayer()) && green[i][j] > maxg) maxg = green[i][j]; + if ((ri->ISBLUE(i,j) || !ri->isBayer()) && 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..85721f631 --- /dev/null +++ b/rtengine/iccjpeg.cc @@ -0,0 +1,245 @@ +/* + * 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..eb4367b48 --- /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}, + {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..910b32718 --- /dev/null +++ b/rtengine/iccstore.cc @@ -0,0 +1,534 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 + void *buf = NULL; + 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 size_t len = (int)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 (int 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 (int 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()) return NULL; + + 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); + loadICCs(usrICCDir, false, fileProfiles, fileProfileContents); + + // 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(); + fileStdProfileContents.clear(); + loadICCs(Glib::build_filename(rtICCDir, "input"), true, fileStdProfiles, fileStdProfileContents); +} + +void ICCStore::loadICCs(Glib::ustring rootDirName, bool nameUpper, std::map& resultProfiles, std::map &resultProfileContents) { + 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); + ProfileContent pc (fname); + if (pc.data) { + cmsHPROFILE profile = pc.toProfile (); + if (profile) { + resultProfiles[name] = profile; + 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; + 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..792271303 --- /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 fileStdProfiles; + std::map fileStdProfileContents; + + cmsHPROFILE xyz; + cmsHPROFILE srgb; + + MyMutex mutex_; + + ICCStore (); + void loadICCs(Glib::ustring rootDirName, bool nameUpper, std::map& resultProfiles, std::map &resultProfileContents); + + 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..b0169be0b --- /dev/null +++ b/rtengine/iimage.cc @@ -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 . + */ + +#include "rtengine.h" + +const char rtengine::sImage8[] = "Image8"; +const char rtengine::sImage16[] = "Image16"; +const char rtengine::sImagefloat[] = "Imagefloat"; diff --git a/rtengine/iimage.h b/rtengine/iimage.h new file mode 100644 index 000000000..0349c6b89 --- /dev/null +++ b/rtengine/iimage.h @@ -0,0 +1,1077 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 +#include +#include "../rtgui/threadutils.h" +#include "rt_math.h" +#include "alignedbuffer.h" +#include "imagedimensions.h" +#include "LUT.h" +#include "coord2d.h" +#include "procparams.h" +#include "color.h" +#include "colortemp.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 + +namespace rtengine { + + extern const char sImage8[]; + extern const char sImage16[]; + extern const char sImagefloat[]; + + 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 (unsigned short srcValue, unsigned char &dstValue) { + dstValue = (unsigned char)(srcValue >> 8); + } + template <> + inline void ImageDatas::convertTo (unsigned char srcValue, int &dstValue) { + dstValue = (int)(srcValue) << 8; + } + template <> + inline void ImageDatas::convertTo (unsigned char srcValue, unsigned short &dstValue) { + dstValue = (unsigned short)(srcValue) << 8; + } + template <> + inline void ImageDatas::convertTo (float srcValue, unsigned char &dstValue) { + dstValue = (unsigned char)( (unsigned short)(srcValue) >> 8 ); + } + template <> + inline void ImageDatas::convertTo (unsigned char srcValue, float &dstValue) { + dstValue = float( (unsigned short)(srcValue) << 8 ); + } + + // -------------------------------------------------------------------- + // Planar order classes + // -------------------------------------------------------------------- + + template + class PlanarPtr { + protected: + AlignedBuffer ab; + public: + T** ptrs; + + PlanarPtr() : ptrs (NULL) {} + 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; + } + + T*& operator() (unsigned row) { return ptrs[row]; } + // Will send back the start of a row, starting with a red, green or blue value + T* operator() (unsigned row) const { return ptrs[row]; } + // Will send back a value at a given row, col position + T& operator() (unsigned row, unsigned col) { return ptrs[row][col]; } + const T operator() (unsigned row, unsigned col) const { return ptrs[row][col]; } + }; + + template + class PlanarImageData : 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) + + public: + T* data; + PlanarPtr r; + PlanarPtr g; + PlanarPtr b; + + PlanarImageData() : rowstride(0), planestride(0), data (NULL) {} + PlanarImageData(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(PlanarImageData &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; + } + + // 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 (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 = rowstride * 3*height; + + 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); + r.resize(0); + g.resize(0); + b.resize(0); + width = height = -1; + 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); + 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) { + PlanarImageData 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 (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) { + + 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 + class ChunkyPtr { + private: + T* ptr; + int width; + public: + ChunkyPtr() : ptr (NULL), width(-1) {} + 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; + } + + // Will send back the start of a row, starting with a red, green or blue value + T* operator() (unsigned row) const { return &ptr[3*(row*width)]; } + // Will send back a value at a given row, col position + T& operator() (unsigned row, unsigned col) { return ptr[3*(row*width+col)]; } + const T operator() (unsigned row, unsigned col) const { return ptr[3*(row*width+col)]; } + }; + + template + class ChunkyImageData : virtual public ImageDatas { + + private: + AlignedBuffer abData; + + public: + T* data; + ChunkyPtr r; + ChunkyPtr g; + ChunkyPtr b; + + ChunkyImageData() : data (NULL) {} + ChunkyImageData(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(ChunkyImageData &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 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 (abData.resize(width*height*3)) { + 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; + } + } + + /** Copy the data to another ChunkyImageData */ + void copyData(ChunkyImageData *dest) { + assert (dest!=NULL); + // Make sure that the size is the same, reallocate if necessary + dest->allocate(width, height); + memcpy (dest->data, data, 3*width*height*sizeof(T)); + } + + void rotate (int deg) { + + if (deg==90) { + ChunkyImageData 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 (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) { + + 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() {} + }; + + /** This class represents an image having a classical 8 bits/pixel representation */ + class IImage8 : public IImage, public ChunkyImageData { + public: + virtual ~IImage8() {} + }; + + /** 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 PlanarImageData { + 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..1f7c7d2bb --- /dev/null +++ b/rtengine/imagedata.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 "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", + "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 (); + 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); + } + 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 (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")) { + 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..2b3f53137 --- /dev/null +++ b/rtengine/imagefloat.cc @@ -0,0 +1,408 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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); + +#ifdef _OPENMP +#pragma omp parallel for +#endif + for (int y=y1; y65535) i=65535; +#ifdef _OPENMP +// Access to hist[] must be atomic. In this case, we may need to see if this parallelization is worth it +#pragma omp atomic +#endif + hist[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..9dc8d8b6d --- /dev/null +++ b/rtengine/imageio.cc @@ -0,0 +1,1172 @@ +/* + * 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); + delete [] loadedProfileData; + 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); + + //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 IMIO_VARIANTNOTSUPPORTED; + } + + 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); + +// 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]; + + 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; +} + +int ImageIO::loadJPEGFromMemory (const char* buffer, int bufsize) +{ + jpeg_decompress_struct cinfo; + jpeg_error_mgr jerr; + cinfo.err = my_jpeg_std_error(&jerr); + jpeg_create_decompress(&cinfo); + + jpeg_memory_src (&cinfo,(const JOCTET*)buffer,bufsize); + 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_memory_src (&cinfo,buffer,bufsize); + jpeg_read_header(&cinfo, TRUE); + + if( loadedProfileData ){ + delete [] loadedProfileData; + loadedProfileData = NULL; + } + 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; + } + else { + jpeg_destroy_decompress(&cinfo); + return IMIO_READERROR; + } +} + +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; + } + + delete loadedProfileData; + loadedProfileData = NULL; + 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) { + +#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; + if( loadedProfileData ){ + delete [] loadedProfileData; + loadedProfileData = NULL; + } + 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_CANNOTREADFILE; + + 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_READERROR; + } + + 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) { + + jpeg_compress_struct cinfo; + jpeg_error_mgr jerr; + + cinfo.err = jpeg_std_error (&jerr); + jpeg_create_compress (&cinfo); + + FILE *file = safe_g_fopen_WriteBinLock (fname); + + if (!file) + return IMIO_CANNOTREADFILE; + + 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); + } + // 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]; + + while (cinfo.next_scanline < cinfo.image_height) { + + getScanline (cinfo.next_scanline, row, 8); + + if (jpeg_write_scanlines (&cinfo, &row, 1) < 1) { + jpeg_finish_compress (&cinfo); + jpeg_destroy_compress (&cinfo); + fclose (file); + return IMIO_READERROR; + } + + 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; + delete [] buffer; + + 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! + + 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_CANNOTREADFILE; + } + + 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); + + bool needsReverse = bps==16 && exifRoot->getOrder()==rtexif::MOTOROLA; + + for (int i=0; isetProgress ((double)(i+1)/height); + } + delete [] buffer; + + 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_CANNOTREADFILE; + } + + 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_READERROR; + } + if (pl && !(row%100)) + pl->setProgress ((double)(row+1)/height); + } + TIFFClose (out); + } + + delete [] linebuffer; + if (pl) { + pl->setProgressStr ("PROGRESSBAR_READY"); + pl->setProgress (1.0); + } + + return IMIO_SUCCESS; +} + +// 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..409852eea --- /dev/null +++ b/rtengine/imageio.h @@ -0,0 +1,130 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 + +#include "rtengine.h" +#include +#include "procparams.h" +#include +#include "../rtexif/rtexif.h" +#include "imagedimensions.h" +#include "iimage.h" +#include "../rtgui/threadutils.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; + +class ImageIO : virtual public ImageDatas { + + protected: + ProgressListener* pl; + cmsHPROFILE embProfile; + char* profileData; + int profileLength; + char* loadedProfileData; + int loadedProfileLength; + procparams::ExifPairs exifChange; + IptcData* iptc; + const rtexif::TagDirectory* exifRoot; + MyMutex imutex; + IIOSampleFormat sampleFormat; + IIOSampleArrangement sampleArrangement; + + public: + static Glib::ustring errorMsg[6]; + + ImageIO () : pl (NULL), embProfile(NULL), profileData(NULL), profileLength(0), loadedProfileData(NULL), + 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..de7cbe6b8 --- /dev/null +++ b/rtengine/imagesource.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 _IMAGESOURCE_ +#define _IMAGESOURCE_ + +#include +#include +#include "rtengine.h" +#include "colortemp.h" +#include "procparams.h" +#include "coord2d.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) {} + // 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, RAWParams raw) =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 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..267b8b03c --- /dev/null +++ b/rtengine/improccoordinator.cc @@ -0,0 +1,915 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 "simpleprocess.h" +#include "../rtgui/ppversion.h" +#include "colortemp.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.f), + + hltonecurve(65536,0), + shtonecurve(65536,2),//clip above + tonecurve(65536,0),//,1); + + lumacurve(65536,0), + chroma_acurve(65536,0), + chroma_bcurve(65536,0), + satcurve(65536,0), + lhskcurve(65536,0), + clcurve(65536,0), + + vhist16(65536),vhist16bw(65536), + lhist16(65536), lhist16Cropped(65536), + lhist16CAM(65536), lhist16CroppedCAM(65536), + lhist16CCAM(65536), + lhist16CCAMAF(65536), lhist16ClabAF(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), + + pW(-1), pH(-1), + plistener(NULL), imageListener(NULL), aeListener(NULL), hListener(NULL),acListener(NULL), abwListener(NULL), + resultValid(false), changeSinceLast(0), updaterRunning(false), destroying(false),utili(false),autili(false), + butili(false),ccutili(false),cclutili(false),clcutili(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 () { + + return new Crop (this); +} + + +// todo: bitmask containing desired actions, taken from changesSinceLast +// cropCall: calling crop, used to prevent self-updates +void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { + + MyMutex::MyLock processingLock(mProcessing); + + int numofphases = 14; + int readyphase = 0; + + bwAutoR = bwAutoG = bwAutoB = -9000.f; + + if (todo==CROP && ipf.needsPCVignetting()) + todo |= TRANSFORM; // Change about Crop does affect TRANSFORM + + // Tells to the ImProcFunctions' tools what is the preview scale, which may lead to some simplifications + ipf.setScale (scale); + + // Check if any detail crops need high detail. If not, take a fast path short cut + bool highDetailNeeded = (todo & M_HIGHQUAL); + 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 + rp.dmethod = RAWParams::methodstring[RAWParams::fast]; + rp.hotdeadpix_filt = false; + rp.ccSteps = 0; + //rp.all_enhance = 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) printf("Demosaic %s\n",rp.dmethod.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 = TR_NONE; + if (params.coarse.rotate==90) tr |= TR_R90; + else if (params.coarse.rotate==180) tr |= TR_R180; + else if (params.coarse.rotate==270) tr |= TR_R270; + + if (params.coarse.hflip) tr |= TR_HFLIP; + if (params.coarse.vflip) tr |= TR_VFLIP; + + imgsrc->getFullSize (fw, fh, tr); + PreviewProps pp (0, 0, fw, fh, scale); + + // Will (re)allocate the preview's buffers + setScale (scale); + + imgsrc->getImage (currWB, tr, orig_prev, pp, params.toneCurve, params.icm, params.raw); + //ColorTemp::CAT02 (orig_prev, ¶ms) ; + + //imgsrc->convertColorSpace(orig_prev, params.icm, params.raw); + + if (todo & M_LINDENOISE) { + //printf("denoising!\n"); + if (scale==1 && params.dirpyrDenoise.enabled) + ipf.RGB_denoise(orig_prev, orig_prev, imgsrc->isRAW(), params.dirpyrDenoise, params.defringe, imgsrc->getDirPyrDenoiseExpComp()); + } + imgsrc->convertColorSpace(orig_prev, params.icm, currWB, params.raw); + + ipf.firstAnalysis (orig_prev, ¶ms, vhist16, imgsrc->getGamma()); + } + 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; + 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 dependend on crop + ipf.g = imgsrc->getGamma(); + ipf.iGamma = true; + CurveFactory::complexCurve (params.toneCurve.expcomp, params.toneCurve.black/65535.0, + params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh, + params.toneCurve.shcompr, params.toneCurve.brightness, params.toneCurve.contrast, + 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); + + CurveFactory::curveBW (params.blackwhite.beforeCurve,params.blackwhite.afterCurve, vhist16bw, histToneCurveBW, beforeToneCurveBW, afterToneCurveBW,scale==1 ? 1 : 1); + + //initialize rrm bbm ggm different from zero to avoid black screen in some cases + double rrm=33.; + double ggm=33.; + double bbm=33.; + + // if it's just crop we just need the histogram, no image updates + if ( todo!=MINUPDATE ) { + ipf.rgbProc (oprevi, oprevl, hltonecurve, shtonecurve, tonecurve, shmap, params.toneCurve.saturation, + rCurve, gCurve, bCurve, customToneCurve1, customToneCurve2,beforeToneCurveBW, afterToneCurveBW, rrm, ggm, bbm, bwAutoR, bwAutoG, bwAutoB, params.toneCurve.expcomp, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh); + 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); + } + // correct GUI black and white with value + } + + // compute L channel histogram + int x1, y1, x2, y2, pos, poscc; + params.crop.mapToResized(pW, pH, scale, x1, x2, y1, y2); + lhist16.clear(); lhist16Cropped.clear(); + lhist16Clad.clear(); lhist16CLlad.clear();lhist16LLClad.clear(); + lhist16ClabAF.clear(); + for (int x=0; xL[x][y])); + lhist16[pos]++; + if (y>=y1 && y=x1 && xCopyFrom(oprevl); + + progress ("Applying Color Boost...",100*readyphase/numofphases); + + ipf.chromiLuminanceCurve (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++; + 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)){ + //if(params.colorappearance.enabled && !params.colorappearance.sharpcie){ + progress ("Pyramid equalizer...",100*readyphase/numofphases); + ipf.dirpyrequalizer (nprevl); + readyphase++; + } + } + + //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(); + lhist16CCAMAF.clear(); + for (int x=0; xL[x][y])); + posc=CLIP((int)sqrt(nprevl->a[x][y]*nprevl->a[x][y] + nprevl->b[x][y]*nprevl->b[x][y])); + if(!params.colorappearance.datacie) lhist16CCAM[posc]++; + if(!params.colorappearance.datacie)lhist16CAM[pos]++; + 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; + double dd; + float **buffer = new float*[pH]; + for (int i=0; iciecamfloat){ + ipf.ciecam_02float (ncie, float(adap), begh, endh, pW, 2, nprevl, ¶ms, customColCurve1,customColCurve2,customColCurve3, histLCAM, histCCAM, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, (float**)buffer, execsharp, d); + 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 + } + else { + ipf.ciecam_02 (ncie, adap, begh, endh, pW, 2, nprevl, ¶ms, customColCurve1,customColCurve2,customColCurve3, histLCAM, histCCAM, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, (float**)buffer, execsharp, dd); + if(params.colorappearance.autodegree && acListener && params.colorappearance.enabled) acListener->autoCamChanged(100.*dd); + if(params.colorappearance.autoadapscen && acListener && params.colorappearance.enabled) acListener->adapCamChanged(adap); + } + + for (int 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 (params.icm.output=="" || params.icm.output==ColorManagementParams::NoICMString) outProfile="sRGB"; + workimg = ipf.lab2rgb (nprevl, 0,0,pW,pH, outProfile, true); + } + 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; + delete shmap; + + } + 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 = 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; + if (params.coarse.hflip) tr |= TR_HFLIP; + if (params.coarse.vflip) tr |= TR_VFLIP; + + int nW, nH; + imgsrc->getFullSize (fw, fh, tr); + + PreviewProps pp (0, 0, fw, fh, prevscale); + imgsrc->getSize (tr, pp, nW, nH); + + 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); + 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); + + 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]++; + } + } + histLuma.clear(); + histChroma.clear(); + for (int i=y1; ia[i][j]*nprevl->a[i][j] + nprevl->b[i][j]*nprevl->b[i][j]))/188]++;//188 = 48000/256 + histLuma[(int)(nprevl->L[i][j]/128)]++; + } + + /*for (int i=0; i<256; i++) { + Lhist[i] = (int)(256*sqrt(Lhist[i])); + rhist[i] = (int)(256*sqrt(rhist[i])); + ghist[i] = (int)(256*sqrt(ghist[i])); + bhist[i] = (int)(256*sqrt(bhist[i])); + bcrgbhist[i] = (int)(256*sqrt(bcrgbhist[i])); + bcLhist[i] = (int)(256*sqrt(bcLhist[i])); + }*/ +} + +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) { + 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 = 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; + if (params.coarse.hflip) tr |= TR_HFLIP; + if (params.coarse.vflip) tr |= TR_VFLIP; + 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) { + + MyMutex::MyLock lock(mProcessing); + + int fW, fH; + imgsrc->getFullSize (fW, fH, 0); + 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 ); + //imgsrc->getImage (imgsrc->getWB(), 0, im, pp, ppar.toneCurve, ppar.icm, 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; + } + params.wb.temperature = currWB.getTemp (); + params.wb.green = currWB.getGreen (); + imgsrc->getImage (currWB, 0, im, pp, ppar.toneCurve, ppar.icm, ppar.raw); + imgsrc->convertColorSpace(im, ppar.icm, currWB, params.raw); + Image16* im16 = im->to16(); + delete im; + im16->saveTIFF (fname,16,true); + delete im16; + //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) { + updaterThreadStart.lock (); + if (!updaterRunning) { + 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); + + } + else + updaterThreadStart.unlock (); + } +} + +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..2fbf63009 --- /dev/null +++ b/rtengine/improccoordinator.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 . + */ +#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; + + LUTf lumacurve; + LUTf chroma_acurve; + LUTf chroma_bcurve; + LUTf satcurve; + LUTf lhskcurve; + LUTf clcurve; + + LUTu vhist16,vhist16bw; + LUTu lhist16,lhist16Cropped; + LUTu lhist16CAM,lhist16CroppedCAM; + LUTu lhist16CCAM; + LUTu lhist16CCAMAF; + LUTu lhist16ClabAF; + 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; + bool utili; + bool autili; + bool butili; + bool ccutili; + bool cclutili; + bool clcutili; + + ToneCurve customToneCurve1; + ToneCurve customToneCurve2; + 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; + + 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; + + 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 (); + + 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); + + 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 saveInputICCReference (const Glib::ustring& fname); + + InitialImage* getInitialImage () { return imgsrc; } +}; +} +#endif diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc new file mode 100644 index 000000000..d005ab52a --- /dev/null +++ b/rtengine/improcfun.cc @@ -0,0 +1,4000 @@ +/* +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 "cplx_wavelet_dec.h" +#include "boxblur.h" +#include "rt_math.h" +#include "EdgePreservingDecomposition.h" +#include "improccoordinator.h" +#ifdef _OPENMP +#include +#endif +#undef CLIPD +#define CLIPD(a) ((a)>0.0f?((a)<1.0f?(a):1.0f):0.0f) +#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; + +#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, double gamma) { + + // 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 (settings->autoMonitorProfile) monitorProfile=iccStore->defaultMonitorProfile; + + cmsHPROFILE monitor = iccStore->getProfile ("file:"+monitorProfile); + if (monitor) { + cmsHPROFILE iprof = iccStore->getXYZProfile (); + lcmsMutex->lock (); + monitorTransform = cmsCreateTransform (iprof, TYPE_RGB_16, monitor, TYPE_RGB_8, settings->colorimetricIntent, + cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is for thread safety, NOOPTIMIZE for precision + 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, float** buffer, bool execsharp, double &d) +{ +if(params->colorappearance.enabled) { + +#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; + } + ColorTemp::curveJ (jli, contra, 1, CAMBrightCurveJ, hist16J);//lightness and contrast J + } + if (needQ) { + if (!CAMBrightCurveQ) { + CAMBrightCurveQ(65536,0); + CAMBrightCurveQ.dirty = false; + } + ColorTemp::curveJ (qbri, qcontra, 1, CAMBrightCurveQ, hist16Q);//brightness and contrast Q + } + } + 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; + + 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; + ColorTemp::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; + ColorTemp::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) +#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 + ColorTemp::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; + ColorTemp::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) ColorTemp::curvecolor(mchr, Mp , sres, parsat); else ColorTemp::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) ColorTemp::curvecolor(schr, Sp , sres, parsat); else ColorTemp::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) ColorTemp::curvecolor(chr, Cp , sres, parsat);else ColorTemp::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); + + 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); + 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 (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); + } + 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 (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); + // 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; + 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->edgePreservingDecompositionUI.enabled ){ + +// if(!params->edgePreservingDecompositionUI.enabled || !params->colorappearance.tonecie || !settings->autocielab){ + // if(!params->edgePreservingDecompositionUI.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 + ColorTemp::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->edgePreservingDecompositionUI.enabled || !params->colorappearance.tonecie || !settings->autocielab){//normal +//if(!params->edgePreservingDecompositionUI.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->colorappearance.badpixsl > 0) if(execsharp){ int mode=params->colorappearance.badpixsl; + ImProcFunctions::badpixcam (ncie, 3.4, 5, mode);//for bad pixels + } + + +if (params->sharpenMicro.enabled)if(execsharp) ImProcFunctions::MLmicrocontrastcam(ncie); + +if(params->sharpening.enabled) if(execsharp) {ImProcFunctions::sharpeningcam (ncie, (float**)buffer);} //sharpening adapted to CIECAM + +if(params->dirpyrequalizer.enabled) if(execsharp) dirpyr_equalizercam(ncie, ncie->sh_p, ncie->sh_p, ncie->W, ncie->H, params->dirpyrequalizer.mult, params->dirpyrequalizer.threshold, true);//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->edgePreservingDecompositionUI.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->edgePreservingDecompositionUI.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; iedgePreservingDecompositionUI.enabled) ncie->J_p[i][j]=(100.0* ncie->Q_p[i][j]*ncie->Q_p[i][j])/(w_h*w_h); + if(params->edgePreservingDecompositionUI.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; + ColorTemp::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, float** buffer, bool execsharp, float &d) +{ +if(params->colorappearance.enabled) { +//printf("ciecam float\n"); +#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); + 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 minM=10000.f; + float maxQ= -1000.f; + float maxM= -1000.f; + float w_h; + float a_w; + float c_; + float f_l; + 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; + + 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.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;} + + 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.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 + float deg=(params->colorappearance.degree)/100.0f; + float pilot=params->colorappearance.autodegree ? 2.0f : 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; + float 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 calculate 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; + } + ColorTemp::curveJfloat (jli, contra, 1, CAMBrightCurveJ, hist16J);//lightness and contrast J + } + if (needQ) { + if (!CAMBrightCurveQ) { + CAMBrightCurveQ(65536,0); + CAMBrightCurveQ.dirty = false; + } + ColorTemp::curveJfloat (qbri, qcontra, 1, CAMBrightCurveQ, hist16Q);//brightness and contrast Q + } + } + 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; + + 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.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; + ColorTemp::initcam1float(gamu, yb, pilot, f, la,xw, yw, zw, n, d, nbb, ncb,cz, aw, wh, pfl, fl, c); + float nj,dj,nbbj,ncbj,czj,awj,flj; + ColorTemp::initcam2float(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,nj, nbbj, ncbj, flj, czj, dj, awj, n, nbb, ncb, pfl, cz) +#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; + float x,y,z; + float epsil=0.0001f; + //convert Lab => XYZ + Color::Lab2XYZ(L, a, b, x1, y1, z1); + float J, C, h, Q, M, s; + float Jp; + float Jpro,Cpro, hpro, Qpro, Mpro, spro; + bool t1L=false; + bool t1B=false; + bool t2B=false; + int c1s=0; + int c1co=0; + + x=(float)x1/655.35f; + y=(float)y1/655.35f; + z=(float)z1/655.35f; + //process source==> normal + ColorTemp::xyz2jchqms_ciecam02float( 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.68f)])/327.68f;//ligthness CIECAM02 + contrast + float sres; + float Sp=spro/100.0f; + float parsat=1.5f; + parsat=1.5f;//parsat=1.5 =>saturation ; 1.8 => chroma ; 2.5 => colorfullness (personal evaluation) + if(schr==-100.0f) schr=-99.8f; + ColorTemp::curvecolorfloat(schr, Sp , sres, parsat); + float coe=pow_F(fl,0.25f); + float dred=100.f;// in C mode + float protect_red=80.0f; // in C mode + dred = 100.0f * sqrt((dred*coe)/Qpro); + protect_red=100.0f * sqrt((protect_red*coe)/Qpro); + int sk=0; + float ko=100.f; + Color::skinredfloat(Jpro, hpro, sres, Sp, dred, protect_red,sk,rstprotection,ko, spro); + Qpro= ( 4.0f / c ) * sqrt( Jpro / 100.0f ) * ( aw + 4.0f ) ; + Cpro=(spro*spro*Qpro)/(10000.0f); + } + else if(alg==3 || alg==0 || alg==2) { + float coef=32760.f/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 + } + float Mp, sres; + float coe=pow_F(fl,0.25f); + Mp=Mpro/100.0f; + float parsat=2.5f; + if(mchr==-100.0f) mchr=-99.8f ; + if(mchr==100.0f) mchr=99.9f; + if(alg==3 || alg==2) ColorTemp::curvecolorfloat(mchr, Mp , sres, parsat); else ColorTemp::curvecolorfloat(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::skinredfloat(Jpro, hpro, sres, Mp, dred, protect_red,sk,rstprotection,ko, Mpro); + Jpro=(100.0f* Qpro*Qpro) /(wh*wh); + Cpro= Mpro/coe; + spro = 100.0f * sqrt( Mpro / Qpro ); + if(alg!=2) { + if(Jpro > 99.9f) + Jpro = 99.9f; + Jpro=(CAMBrightCurveJ[(float)(Jpro*327.68f)])/327.68f;//ligthness CIECAM02 + contrast + } + float Cp; + float Sp=spro/100.0f; + parsat=1.5f; + if(schr==-100.0f) schr=-99.f; + if(schr==100.0f) schr=98.f; + if(alg==3) ColorTemp::curvecolorfloat(schr, Sp , sres, parsat); else ColorTemp::curvecolorfloat(0.0f, Sp , sres, parsat); //saturation + dred=100.f;// in C mode + protect_red=80.0f; // in C mode + dred = 100.0f * sqrt((dred*coe)/Q); + protect_red=100.0f * sqrt((protect_red*coe)/Q); + sk=0; + Color::skinredfloat(Jpro, hpro, sres, Sp, dred, protect_red,sk,rstprotection,ko, spro); + Qpro= ( 4.0f / c ) * sqrt( Jpro / 100.0f ) * ( aw + 4.0f ) ; + Cpro=(spro*spro*Qpro)/(10000.0f); + Cp=Cpro/100.0f; + parsat=1.8f;//parsat=1.5 =>saturation ; 1.8 => chroma ; 2.5 => colorfullness (personal evaluation : for not) + if(chr==-100.0f) chr=-99.8f; + if(alg!=2) ColorTemp::curvecolorfloat(chr, Cp , sres, parsat);else ColorTemp::curvecolorfloat(0.0f, Cp , sres, parsat); //chroma + dred=55.f; + protect_red=30.0f; + sk=1; + Color::skinredfloat(Jpro, hpro, sres, Cp, dred, protect_red,sk,rstprotection, ko, Cpro); + + 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); + 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=(float)(Qq*(coef)/327.68f); + Jpro=100.f*(Qpro*Qpro)/((4.0f/c)*(4.0f/c)*(aw+4.0f)*(aw+4.0f)); + t1B=true; + } + } + + 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); + } + 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)); + 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.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 (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; + float sk=1; + float ko=1.f/coef; + Color::skinredfloat(Jpro, hpro, Cc, Ccold, dred, protect_red,sk,rstprotection,ko, Cpro); + } + 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 coe=pow_F(fl,0.25f); + float dred=100.f;// in C mode + float protect_red=80.0f; // in C mode + dred = 100.0f * sqrt((dred*coe)/Qpro); + protect_red=100.0f * sqrt((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 ) * sqrt( Jpro / 100.0f ) * ( aw + 4.0f ) ; + Cpro=(spro*spro*Qpro)/(10000.0f); + c1s=1; + + } + 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 coe=pow_F(fl,0.25f); + 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; + c1co=1; + } + } + //to retrieve the correct values of variables + + if(c1s==1) { + Qpro= ( 4.0f / c ) * sqrt( Jpro / 100.0f ) * ( aw + 4.0f ) ;//for saturation curve + Cpro=(spro*spro*Qpro)/(10000.0f); + } + if(c1co==1) { 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 + float Qred= ( 4.0f / c) * ( aw + 4.0f );//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->sh_p[i][j]=(float) 32768.f*(( 4.0f / c )*sqrt( J / 100.0f ) * ( aw + 4.0f ))/Qred ; + 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->edgePreservingDecompositionUI.enabled){ + 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;} + + 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]++; + } + } + float xx,yy,zz; + //process normal==> viewing + + ColorTemp::jch2xyz_ciecam02float( 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.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); + 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=xatan2f(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; + float2 sincosval = xsincosf(HH); + + lab->a[i][j]=327.68f*Chprov1*sincosval.y; + lab->b[i][j]=327.68f*Chprov1*sincosval.x; + + } + } + } + } + // End of parallelization +if(!params->colorappearance.tonecie || !settings->autocielab){//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.0f*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.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) { + + + +//all this treatments reduce artefacts, but can leed to slighty different results + +if(params->defringe.enabled) if(execsharp) ImProcFunctions::defringecam (ncie);//defringe adapted to CIECAM + +if(params->colorappearance.badpixsl > 0) if(execsharp){ int mode=params->colorappearance.badpixsl; + ImProcFunctions::badpixcam (ncie, 3.0, 10, mode);//for bad pixels + } + +if(params->impulseDenoise.enabled) if(execsharp) ImProcFunctions::impulsedenoisecam (ncie);//impulse adapted to CIECAM + +if (params->sharpenMicro.enabled)if(execsharp) ImProcFunctions::MLmicrocontrastcam(ncie); + +if(params->sharpening.enabled) if(execsharp) {ImProcFunctions::sharpeningcam (ncie, (float**)buffer);} //sharpening adapted to CIECAM + +if(params->dirpyrequalizer.enabled) if(execsharp) dirpyr_equalizercam(ncie, ncie->sh_p, ncie->sh_p, ncie->W, ncie->H, params->dirpyrequalizer.mult, params->dirpyrequalizer.threshold, true);//contrast by detail adapted to CIECAM + + float Qredi= ( 4.0f / c_) * ( a_w + 4.0f ); + float co_e=(pow_F(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.0f* interm*interm/((a_w+4.f)*(a_w+4.f)*(4.f/c_)*(4.f/c_)); + ncie->Q_p[i][j]=( 4.0f / c_) * ( a_w + 4.0f ) * 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->edgePreservingDecompositionUI.enabled)) || (params->sharpening.enabled && settings->autocielab) + || (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(params->edgePreservingDecompositionUI.enabled && params->colorappearance.tonecie && algepd) ImProcFunctions::EPDToneMapCIE(ncie, a_w, c_, w_h, width, height, begh, endh, minQ, maxQ, Iterates, scale ); + //EPDToneMapCIE adated 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,nj, nbbj, ncbj, flj, czj, dj, awj) +#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; iedgePreservingDecompositionUI.enabled) ncie->J_p[i][j]=(100.0f* ncie->Q_p[i][j]*ncie->Q_p[i][j])/(w_h*w_h); + if(params->edgePreservingDecompositionUI.enabled) ncie->J_p[i][j]=(100.0f* ncie->Q_p[i][j]*ncie->Q_p[i][j])/SQR((4.f/c)*(aw+4.f)); + + 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; + 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;} + 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 + + ColorTemp::jch2xyz_ciecam02float( 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.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); + 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=xatan2f(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 + float2 sincosval = xsincosf(HH); + + 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; + } + } + + + } + //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.0f*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.0f*CLIPD(hvalc)); // + histCCAM[hic] += hist16_CCAM[i] ; + } + } + } + } + + } +} +} +//end CIECAM +void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, + SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, + const ToneCurve & customToneCurve1,const ToneCurve & customToneCurve2, const ToneCurve & customToneCurvebw1,const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob ) { + rgbProc (working, lab, hltonecurve, shtonecurve, tonecurve, shmap, sat, rCurve, gCurve, bCurve, customToneCurve1, customToneCurve2, customToneCurvebw1, customToneCurvebw2,rrm, ggm, bbm, autor, autog, autob, params->toneCurve.expcomp, params->toneCurve.hlcompr, params->toneCurve.hlcomprthresh); +} + +// Process RGB image and convert to LAB space +void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, + SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, 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) { + + LUTf iGammaLUTf; + Imagefloat *tmpImage; + + 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); + + double pi = M_PI; + 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 (sCurveEnabled) sCurve = new FlatCurve(params->hsvequalizer.scurve); + if (vCurveEnabled) vCurve = new FlatCurve(params->hsvequalizer.vcurve); + if (bwlCurveEnabled) { + bwlCurve = new FlatCurve(params->blackwhite.luminanceCurve); + if (bwlCurve->isIdentity()) { + delete bwlCurve; + bwlCurve = NULL; + bwlCurveEnabled = false; + } + } + + 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; + + // extracting datas from 'params' to avoid cache flush (to be confirmed) + ToneCurveParams::eTCModeId curveMode = params->toneCurve.curveMode; + ToneCurveParams::eTCModeId curveMode2 = params->toneCurve.curveMode2; + 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); + + 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(blackwhite) + tmpImage = new Imagefloat(working->width,working->height); + +#define TS 112 + +#ifdef _OPENMP +#pragma omp parallel if (multiThread) +#endif +{ + char *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; + +#pragma omp for schedule(dynamic) collapse(2) nowait + 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; 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]); + } + } + } + } + + if (hasToneCurve2) { + if (curveMode2==ToneCurveParams::TC_MODE_STD){ // Standard + 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; 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; itoneCurve.hrenabled;//Get the value if "highlight reconstruction" is activated + + float r1,g1,b1, r2,g2,b2, L_1,L_2, Lfactor,a_1,b_1,x_,y_,z_,R,G,B ; + float y,fy, yy,fyy,x,z,fx,fz; + + // rgb values before RGB curves + r1 = rtemp[ti*TS+tj] ; + g1 = gtemp[ti*TS+tj] ; + b1 = btemp[ti*TS+tj] ; + //convert to Lab to get a&b before RGB curves + x = toxyz[0][0] * r1 + toxyz[0][1] * g1 + toxyz[0][2] * b1; + y = toxyz[1][0] * r1 + toxyz[1][1] * g1 + toxyz[1][2] * b1; + z = toxyz[2][0] * r1 + toxyz[2][1] * g1 + toxyz[2][2] * b1; + + 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 )))); + + L_1 = (116.0f * fy - 5242.88f); //5242.88=16.0*327.68; + a_1 = (500.0f * (fx - fy) ); + b_1 = (200.0f * (fy - fz) ); + + // rgb values after RGB curves + if (rCurve) r2 = rCurve[ rtemp[ti*TS+tj]]; else r2=r1; + if (gCurve) g2 = gCurve[ gtemp[ti*TS+tj]]; else g2=g1; + if (bCurve) b2 = bCurve[ btemp[ti*TS+tj]]; else b2=b1; + + // Luminosity after + // only Luminance in Lab + yy = toxyz[1][0] * r2 + toxyz[1][1] * g2 + toxyz[1][2] * b2; + fyy = (yy<65535.0f ? cachef[std::max(yy,0.f)] : (327.68f*float(exp(log(yy/MAXVALF)/3.0f )))); + L_2 = (116.0f * fyy - 5242.88f); + + //gamut control + if(settings->rgbcurveslumamode_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 (sat!=0 || hCurveEnabled || sCurveEnabled || vCurveEnabled) { + 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]); + } + } + } + + //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; itoneCurve.hrenabled;//Get the value if "highlight reconstruction" is activated + //rgb=>lab + 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; + float valparam = float((bwlCurve->getVal((hr=Color::huelab_to_huehsv2(HH)))-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, a_, b_, X, Y, Z); + float rr_,gg_,bb_; + Color::xyz2rgb(X,Y,Z,rr_,gg_,bb_,wip); + + //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; iL[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 tmoImage and close the tiled processing + for (int i=istart,ti=0; ir(i,j) = rtemp[ti*TS+tj]; + tmpImage->g(i,j) = gtemp[ti*TS+tj]; + tmpImage->b(i,j) = btemp[ti*TS+tj]; + } + } + } + } + free(buffer); +} + + //black and white + if(blackwhite){ + int tW = working->width; + int tH = working->height; + +/* + else if (algm==1) {//Luminance mixer +#ifdef _OPENMP +#pragma omp for schedule(dynamic, 5) +#endif + for (int i=0; ir(i,j); + float g = tmpImage->g(i,j); + float b = tmpImage->b(i,j); + if (bwlCurveEnabled) { + float h,s,v; + Color::rgb2hsv(r,g,b,h,s,v); + if (v<0) v=0; + float valparam = bwlCurve->getVal((double)h)-0.5f; + valparam *= (1.f-(SQR(SQR(1.f-min(s,1.0f))))); + //float valcor=1.f/(0.501f-valparam); + + if (valparam < -0.00001f || valparam > 0.00001f) + v *= (1.f + 4.f*valparam); + v = CLIPD(v); + Color::hsv2rgb(h, s, v, r, g, b); + } + + // get luminance + r = g = b = (0.2126f*r + 0.7152f*g + 0.0722f*b); // (constant taken from Gimp, see https://git.gnome.org/browse/gimp/tree/libgimpcolor/gimprgb.h) + //r = g = b = (0.299f*r + 0.587f*g + 0.114f*b); // (obsolete constant) + + //gamma correction: pseudo TRC curve + if (hasgammabw) Color::trcGammaBW (r, g, b, gammabwr, gammabwg, gammabwb); + + tmpImage->r(i,j) = r; + tmpImage->g(i,j) = g; + tmpImage->b(i,j) = b; + } + } + } +*/ + + 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; + } + + Color::computeBWMixerConstants(params->blackwhite.setting, params->blackwhite.filter, + 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; + + float in[3], val[3]; + +#ifdef _OPENMP +#pragma omp patallel 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 (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)); + } + } + } + } + +#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; + } + + +// delete tmpImage; + + if (hCurveEnabled) delete hCurve; + if (sCurveEnabled) delete sCurve; + if (vCurveEnabled) delete vCurve; + +} + + +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]; + } +} + + + +void ImProcFunctions::chromiLuminanceCurve (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) + 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()) { + chutili=true; + }//do not use "Munsell" if Chcurve not used + } + 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()) { + 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()) { + hhutili=true; + } + } + + LUTf dCcurve(65536,0); + LUTf dLcurve(65536,0); + + LUTu hist16Clad(65536); + LUTu hist16CLlad(65536); + LUTu hist16LLClad(65536); + + bool chrop=false; + float val; + //preparate for histograms CIECAM + if(pW!=1){//only with improccoordinator + chrop = true; + 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(); + hist16CLlad.clear(); + hist16LLClad.clear(); + + } +#ifdef _DEBUG + MyTime t1e,t2e, t3e, t4e; + t1e.set(); + // init variables to display Munsell corrections + MunsellDebugInfo* MunsDebugInfo = new MunsellDebugInfo(); +#endif + + + float adjustr=1.0f, adjustbg=1.0f; + +// if(params->labCurve.avoidclip ){ + // parameter to adapt curve C=f(C) to gamut + + if (params->icm.working=="ProPhoto") {adjustr = adjustbg = 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; 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;} + + + // reference to the params structure has to be done outside of the parallelization to avoid CPU cache problem + bool highlight = params->toneCurve.hrenabled; //Get the value if "highlight reconstruction" is activated + int chromaticity = params->labCurve.chromaticity; + bool bwToning = params->labCurve.chromaticity==-100 /*|| params->blackwhite.method=="Ch" */ || params->blackwhite.enabled; + //if(chromaticity==-100) chromaticity==-99; + //if(bwToning) printf("OK bwto\n"); else printf("pas de bw\n"); + bool LCredsk = params->labCurve.lcredsk; + bool ccut = ccutili; + bool clut = clcutili; + 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 + bool avoidColorShift = (params->labCurve.avoidcolorshift || (params->colorappearance.gamut && params->colorappearance.enabled)) && !bwToning ; + int protectRed = settings->protectred; + double protectRedH = settings->protectredh; + bool gamutLch = settings->gamutLch; + float amountchroma = (float) settings->amchroma; + // only if user activate Lab adjustements + if (avoidColorShift) { + if(autili || butili || ccutili || cclutili || chutili || lhutili || hhutili || clcutili || utili || chromaticity) { + unsigned int N = W*H; + float *L = lold->L[0]; + float *a= lold->a[0]; + float *b= lold->b[0]; + float* Lold = new float [N];//to save L before any used + float* Cold = new float [N];//to save C before any used +#ifdef _OPENMP +#pragma omp parallel for if (multiThread) +#endif // _OPENMP + for (unsigned int j=0; jtoneCurve.hrenabled, /*gamut*/true, params->icm.working, multiThread); + delete [] Lold; + delete [] Cold; + } + } + +#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 default(shared) firstprivate(highlight, ccut, clut, chromaticity, bwToning, rstprotection, avoidColorShift, LCredsk, protectRed, protectRedH, gamutLch, lold, lnew, pW) if (multiThread) +#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]} + }; + + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + 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]}}; + +#pragma omp for schedule(dynamic, 16) + for (int i=0; iL[i][j]/327.68f; + float CC=sqrt(SQR(lold->a[i][j]) + SQR(lold->b[i][j]))/327.68f; + float HH=xatan2f(lold->b[i][j],lold->a[i][j]); + // According to mathematical laws we can get the sin and cos of HH by simple operations + float2 sincosval; + 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); + } + + float Chprov=CC; + float Chprov1=CC; + float memChprov=Chprov; + + float Lin=lold->L[i][j]; + float Lprov2=Lin/327.68f; + lnew->L[i][j] = curve[Lin]; + float Lprov1=(lnew->L[i][j])/327.68f; + float chromaChfactor=1.0f; + float atmp = acurve[lold->a[i][j]+32768.0f]-32768.0f;// curves Lab a + float btmp = bcurve[lold->b[i][j]+32768.0f]-32768.0f;// curves Lab b + float Chprov2=Chprov1; + int poscc,posp,posl; + bool inRGB; + const float ClipLevel = 65535.0f; + + if (lhutili) { // L=f(H) + float l_r;//Luminance Lab in 0..1 + l_r = Lprov1/100.f; + { + double lr; + float khue=1.9f;//in reserve in case of! + float valparam = float((lhCurve->getVal(lr=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 + //reduct 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 {l_r *= (1.f+khue*valparamneg);}//for negative + } + + Lprov1=l_r*100.f; + + Chprov2 = sqrt(SQR(atmp/327.68f)+SQR(btmp/327.68f)); + //Gamut control especialy fot negative values slightly different of gamutlchonly + 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.999f) Lprov1 = 99.98f; + Chprov2 *= 0.95f; + inRGB = false; + } + } + while (!inRGB) ; + +// float2 sincosval = xsincosf(HH); + atmp=327.68f*Chprov2*sincosval.y; + btmp=327.68f*Chprov2*sincosval.x; + + } +// calculate C=f(H) + if (chutili) { + double hr; + float chparam = float((chCurve->getVal((hr=Color::huelab_to_huehsv2(HH)))-0.5f) * 2.0f);//get C=f(H) + chromaChfactor=1.0f+chparam; + } + + atmp *= chromaChfactor;//apply C=f(H) + btmp *= chromaChfactor; + + if (hhutili) { // H=f(H) + //hue Lab in -PI +PI + double hr; + float valparam = float((hhCurve->getVal(hr=Color::huelab_to_huehsv2(HH))-0.5f) * 1.7f) +HH;//get H=f(H) 1.7 optimisation ! + HH= valparam; + } + + //simulate very approximative gamut f(L) : with pyramid transition + float dred=55.0f;//C red value limit + if (Lprov1<25.0f) dred = 40.0f; + else if(Lprov1<30.0f) dred = 3.0f*Lprov1 -35.0f; + else if(Lprov1<70.0f) dred = 55.0f; + else if(Lprov1<75.0f) dred = -3.0f*Lprov1 +265.0f; + else dred = 40.0f; + // end pyramid + if(params->dirpyrDenoise.enabled && chromaticity ==0) chromaticity = 0.5f; + + if(!bwToning){ + float chromahist; + 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_red,protect_redh; + float deltaHH;//HH value transition + protect_red=float(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 + + deltaHH=protect_redh;//transition hue + float chromapro = (chromaticity + 100.0f)/100.0f; + if(chromapro>0.0) Color::scalered ( rstprotection, chromapro, 0.0, HH, deltaHH, scale, scaleext);//1.0 + if(chromapro>1.0) {interm=(chromapro-1.0f)*100.0f; + factorskin= 1.0f+(interm*scale)/100.0f; + factorskinext=1.0f+(interm*scaleext)/100.0f;} + else { + //factorskin= chromapro*scale; + //factorskinext= chromapro*scaleext; + factorskin= chromapro ; // +(chromapro)*scale; + factorskinext= chromapro ;// +(chromapro)*scaleext; + + } + factorsat=chromapro; + //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 + } + factorsat*=factnoise; + + factor=factorsat; + // Test if chroma is in the normal range first + Color::transitred ( HH, Chprov1, dred, factorskin, protect_red, factorskinext, deltaHH, factorsat, factor); + atmp *= factor; + btmp *= factor; + + } + + if (!bwToning && clut) { // begin C=f(L) + float factorskin,factorsat,factor,factorskinext,interm; + float chroma = sqrt(SQR(atmp)+SQR(btmp)+0.001f); + // float chromaCfactor=(clcurve[Lprov1*327.68f])/(Lprov1*327.68f);//apply C=f(L) + float chromaCfactor=(clcurve[Lprov2*327.68f])/(Lprov2*327.68f);//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*float(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) + + // I have placed C=f(C) after all C treatments to assure maximum amplitude of "C" + if (!bwToning && 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*float(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 + posp=CLIP((int)sqrt((atmp*atmp + btmp*btmp))); + hist16Clad[posp]++; + hist16CLlad[posp]++; + + } + + if (!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 protect_redhcur; + float curf=1.0f; + float deltaHH; + protect_redhcur=curf*float(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 + + deltaHH=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 artefact, 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=(Chprov1/chrmin)*(Chprov1/chrmin)*xx;else yy=xx;//avoid artefact for low C + if(!LCredsk) {skbeg=-3.1415; skend=3.14159; deltaHH=0.001f;} + if(HH>skbeg && HH < skend ) zz=yy; + else if(HH>skbeg-deltaHH && HH<=skbeg) {aa=yy/deltaHH;bb=-aa*(skbeg-deltaHH); zz=aa*HH+bb;}//transition + else if(HH>=skend && HH < skend+deltaHH) {aa=-yy/deltaHH;bb=-aa*(skend+deltaHH);zz=aa*HH+bb;}//transition + + 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 L + if(pW!=1){//only with improccoordinator + posl=CLIP((int(Lprov1*327.68f))); + hist16LLClad[posl]++; + } + + Chprov1 = sqrt(SQR(atmp/327.68f)+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,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 + 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.0f; // Munsell's correction + float correctlum=0.0f; + + Lprov1=lnew->L[i][j]/327.68f; + Chprov=sqrt(SQR(lnew->a[i][j]/327.68f)+ SQR(lnew->b[i][j]/327.68f)); + +#ifdef _DEBUG + Color::AllMunsellLch(/*lumaMuns*/true, Lprov1,Lprov2,HH,Chprov,memChprov,correctionHue,correctlum, MunsDebugInfo); +#else + Color::AllMunsellLch(/*lumaMuns*/true, Lprov1,Lprov2,HH,Chprov,memChprov,correctionHue,correctlum); +#endif + + 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. + */ + float2 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 + ... + if (chrop) { + float hval = dCcurve[i]; + int hi = (int)(255.0*CLIPD(hval)); // + histCCurve[hi] += hist16Clad[i] ; + histCLurve[hi] += hist16CLlad[i] ; + } + } + //update histogram L with data luminance + for (int i=0; i<=65535; i++) { + if (chrop) { + float hlval = dLcurve[i]; + int hli = (int)(255.0*CLIPD(hlval)); + histLLCurve[hli] += hist16LLClad[i] ; + histLCurve[hli] += hist16LLClad[i] ; + + } + } + + } + +#ifdef _DEBUG + if (settings->verbose) { + t3e.set(); + printf("Color::AllMunsellLch (correction performed in %d usec):\n", t3e.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; +} + + +//#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) { + + if (params->impulseDenoise.enabled && ncie->W>=8 && ncie->H>=8) + + impulse_nrcam (ncie, (float)params->impulseDenoise.thresh/20.0 ); + } + + 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){ + if(ncie->W>=8 && ncie->H>=8) Badpixelscam(ncie, ncie, rad, thr, mode); + } + + void ImProcFunctions::dirpyrequalizer (LabImage* lab) { + + if (params->dirpyrequalizer.enabled && lab->W>=8 && lab->H>=8) { + + //dirpyrLab_equalizer(lab, lab, params->dirpyrequalizer.mult); + dirpyr_equalizer(lab->L, lab->L, lab->W, lab->H, params->dirpyrequalizer.mult, params->dirpyrequalizer.threshold); + } + } +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->edgePreservingDecompositionUI.enabled) return; + float stren=params->edgePreservingDecompositionUI.Strength; + float edgest=params->edgePreservingDecompositionUI.EdgeStopping; + float sca=params->edgePreservingDecompositionUI.Scale; + float rew=params->edgePreservingDecompositionUI.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]; + float eps=0.0001; + if (settings->verbose) printf("minQ=%f maxQ=%f Qpro=%f\n",minQ,maxQ, Qpro); + if(maxQ>Qpro) Qpro=maxQ; + for (int i=0; iQ_p[i][j];} + + EdgePreservingDecomposition epd = EdgePreservingDecomposition(Wid, Hei); + + for(i = 0; i != N; i++) Qpr[i] = (Qpr[i]+eps)/(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]=(Qpr[i*Wid+j]+eps)*Qpro; + 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->edgePreservingDecompositionUI); + + //Enabled? Leave now if not. +// if(!p->enabled) return; +if(!params->edgePreservingDecompositionUI.enabled) return; +float stren=params->edgePreservingDecompositionUI.Strength; +float edgest=params->edgePreservingDecompositionUI.EdgeStopping; +float sca=params->edgePreservingDecompositionUI.Scale; +float rew=params->edgePreservingDecompositionUI.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; +#pragma omp parallel +{ + float lminL = FLT_MAX; +#pragma omp for + for(i = 0; i < N; i++) + if(L[i] < lminL) lminL = L[i]; +#pragma omp critical + if(lminL < minL) minL = lminL; +} + 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; + + //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 + 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; + } + + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + 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 = calcDistortion (thumbGray, rawGray, width, h_thumb); + 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..e496275e0 --- /dev/null +++ b/rtengine/improcfun.h @@ -0,0 +1,299 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 "curves.h" +#include +#include "cplx_wavelet_dec.h" + + +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); + 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..402b83b6f --- /dev/null +++ b/rtengine/impulse_denoise.h @@ -0,0 +1,543 @@ +/* + * 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" +#ifdef __SSE2__ +#include "sleefsseavx.c" +#endif + +using namespace std; + +namespace rtengine { + +#if defined( __SSE2__ ) && defined( WIN32 ) +__attribute__((force_align_arg_pointer)) void ImProcFunctions::impulse_nr (LabImage* lab, double thresh) +#else +void ImProcFunctions::impulse_nr (LabImage* lab, double thresh) +#endif +{ + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // 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 = new float *[height]; + // buffer for the highpass image + float ** impish = new float *[height]; + 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 + } +} + + //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 + +// 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 + } +} + + 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 "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..b42760782 --- /dev/null +++ b/rtengine/iplab2rgb.cc @@ -0,0 +1,491 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 "mytime.h" +#include "../rtgui/icmpanel.h" +#include "../rtgui/options.h" +#include "settings.h" +#include "curves.h" +#include "alignedbuffer.h" +#include "color.h" + + +#ifdef _OPENMP +#include +#endif + +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) { + //MyTime tBeg,tEnd; + // tBeg.set(); + //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); + unsigned short *buffer=pBuf.data; + +#ifdef _OPENMP +#pragma omp for schedule(static) +#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; jColor::epskap) ? fy*fy*fy : LL/Color::kappa; + + z_ = Color::f2xyz(fz)*Color::D50z; + + buffer[iy++] = (unsigned short)CLIP(x_* MAXVALF+0.5); + buffer[iy++] = (unsigned short)CLIP(y_* MAXVALF+0.5); + buffer[iy++] = (unsigned short)CLIP(z_* MAXVALF+0.5); + } + + cmsDoTransform (monitorTransform, buffer, data + ix, W); + +} // End of parallelization + + } + } else { + + int W = lab->W; + int H = lab->H; + unsigned char * data = image->data; + +#ifdef _OPENMP +#pragma omp parallel for schedule(static) firstprivate(lab, data, W, H) 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; + } + } + } + + //tEnd.set(); + //printf("lab2rgb %i %d\n", lab->W, tEnd.etime(tBeg)); +} + +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); + } + cmsHPROFILE iprof = iccStore->getXYZProfile (); + lcmsMutex->lock (); + cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprofG, TYPE_RGB_8, settings->colorimetricIntent, + cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is important for thread safety + lcmsMutex->unlock (); + + unsigned char *data = image->data; + + // cmsDoTransform is relatively expensive +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + AlignedBuffer pBuf(3*cw); + unsigned short *buffer=pBuf.data; + int condition = cy+ch; + +#ifdef _OPENMP +#pragma omp for firstprivate(lab) schedule(static) +#endif + for (int i=cy; iL[i]; + float* ra = lab->a[i]; + float* rb = lab->b[i]; + + for (int j=cx; jColor::epskap) ? 65535.0*fy*fy*fy : 65535.0*LL/Color::kappa; + + buffer[iy++] = CLIP((int)(x_+0.5)); + buffer[iy++] = CLIP((int)(y_+0.5)); + buffer[iy++] = CLIP((int)(z_+0.5)); + } + + cmsDoTransform (hTransform, buffer, data + ix, cw); + } +} // End of parallelization + + cmsDeleteTransform(hTransform); + if (oprofG != oprof) + cmsCloseProfile(oprofG); + } else { + + double rgb_xyz[3][3]; + + for (int i=0; iL[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) { + + //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.0*fy*fy*fy : 65535.0*LL/Color::kappa; + + xa[j-cx] = CLIP((int)(x_+0.5)); + ya[j-cx] = CLIP((int)(y_+0.5)); + za[j-cx] = CLIP((int)(z_+0.5)); + } + } + + 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) ? 65535.0*fy*fy*fy : 65535.0*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) { + + //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) ? 65535.0*fy*fy*fy : 65535.0*LL/Color::kappa; + + xa[j-cx] = CLIP((int)x_); + ya[j-cx] = CLIP((int)y_); + za[j-cx] = CLIP((int)z_); + } + } + + 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) ? 65535.0*fy*fy*fy : 65535.0*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..382be169a --- /dev/null +++ b/rtengine/ipresize.cc @@ -0,0 +1,291 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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" + +#ifdef _OPENMP +#include +#endif + +//#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 sinf(x) * sinf(x / a) / (x * x / a); + } +} + +static void 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; + + // 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 + + 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; +} + +void ImProcFunctions::resize (Image16* src, Image16* dst, float dScale) { + +#ifdef PROFILE + time_t t1 = clock(); +#endif + + if(params->resize.method == "Lanczos" || + params->resize.method == "Downscale (Better)" || + params->resize.method == "Downscale (Faster)" + ) { + Lanczos(src, dst, dScale); + } + else if (params->resize.method.substr(0,7)=="Bicubic") { + float Av = -0.5f; + if (params->resize.method=="Bicubic (Sharper)") + Av = -0.75f; + else if (params->resize.method=="Bicubic (Softer)") + Av = -0.25f; + #pragma omp parallel for if (multiThread) + for (int i=0; iheight; i++) { + float wx[4], wy[4]; + float Dy = i / dScale; + int yc = (int) Dy; + Dy -= (float)yc; + int ys = yc - 1; // smallest y-index used for interpolation + // compute vertical weights + float t1y = -Av*(Dy-1.0f)*Dy; + float t2y = (3.0f - 2.0f*Dy)*Dy*Dy; + wy[3] = t1y*Dy; + wy[2] = t1y*(Dy - 1.0f) + t2y; + wy[1] = -t1y*Dy + 1.0f - t2y; + wy[0] = -t1y*(Dy - 1.0f); + for (int j = 0; j < dst->width; j++) { + float Dx = j / dScale; + int xc = (int) Dx; + Dx -= (float)xc; + int xs = xc - 1; // smallest x-index used for interpolation + if (ys >= 0 && ys < src->height-3 && xs >= 0 && xs <= src->width-3) { + // compute horizontal weights + float t1 = -Av*(Dx-1.0f)*Dx; + float t2 = (3.0f - 2.0f*Dx)*Dx*Dx; + wx[3] = t1*Dx; + wx[2] = t1*(Dx - 1.0f) + t2; + wx[1] = -t1*Dx + 1.0f - t2; + wx[0] = -t1*(Dx - 1.0f); + // compute weighted sum + int r = 0; + int g = 0; + int b = 0; + for (int x=0; x<4; x++) + for (int y=0; y<4; y++) { + float w = wx[x]*wy[y]; + r += w*src->r(ys+y,xs+x); + g += w*src->g(ys+y,xs+x); + b += w*src->b(ys+y,xs+x); + } + dst->r(i,j) = CLIP(r); + dst->g(i,j) = CLIP(g); + dst->b(i,j) = CLIP(b); + } + else { + xc = LIM(xc, 0, src->width-1); + yc = LIM(yc, 0, src->height-1); + int nx = xc + 1; + if (nx >= src->width) + nx = xc; + int ny = yc + 1; + if (ny >= src->height) + ny = yc; + dst->r(i,j) = (1-Dx)*(1-Dy)*src->r(yc,xc) + (1-Dx)*Dy*src->r(ny,xc) + Dx*(1-Dy)*src->r(yc,nx) + Dx*Dy*src->r(ny,nx); + dst->g(i,j) = (1-Dx)*(1-Dy)*src->g(yc,xc) + (1-Dx)*Dy*src->g(ny,xc) + Dx*(1-Dy)*src->g(yc,nx) + Dx*Dy*src->g(ny,nx); + dst->b(i,j) = (1-Dx)*(1-Dy)*src->b(yc,xc) + (1-Dx)*Dy*src->b(ny,xc) + Dx*(1-Dy)*src->b(yc,nx) + Dx*Dy*src->b(ny,nx); + } + } + } + } + else if (params->resize.method=="Bilinear") { + #pragma omp parallel for if (multiThread) + for (int i=0; iheight; i++) { + int sy = i/dScale; + sy = LIM(sy, 0, src->height-1); + float dy = i/dScale - sy; + int ny = sy+1; + if (ny>=src->height) + ny = sy; + for (int j=0; jwidth; j++) { + int sx = j/dScale; + sx = LIM(sx, 0, src->width-1); + float dx = j/dScale - sx; + int nx = sx+1; + if (nx>=src->width) + nx = sx; + dst->r(i,j) = (1-dx)*(1-dy)*src->r(sy,sx) + (1-dx)*dy*src->r(ny,sx) + dx*(1-dy)*src->r(sy,nx) + dx*dy*src->r(ny,nx); + dst->g(i,j) = (1-dx)*(1-dy)*src->g(sy,sx) + (1-dx)*dy*src->g(ny,sx) + dx*(1-dy)*src->g(sy,nx) + dx*dy*src->g(ny,nx); + dst->b(i,j) = (1-dx)*(1-dy)*src->b(sy,sx) + (1-dx)*dy*src->b(ny,sx) + dx*(1-dy)*src->b(sy,nx) + dx*dy*src->b(ny,nx); + } + } + } + else { + // Nearest neighbour algorithm + #pragma omp parallel for if (multiThread) + 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..1d0672ebe --- /dev/null +++ b/rtengine/ipsharpen.cc @@ -0,0 +1,1072 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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" +#ifdef __SSE2__ +#include "sleefsseavx.c" +#endif +#ifdef _OPENMP +#include +#endif + +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; +#if defined( __SSE__ ) && defined( WIN32 ) +__attribute__((force_align_arg_pointer)) void ImProcFunctions::dcdamping (float** aI, float** aO, float damping, int W, int H) { +#else +void ImProcFunctions::dcdamping (float** aI, float** aO, float damping, int W, int H) { +#endif + + 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; isharpening.enabled==false || params->sharpening.deconvamount<1) + return; + + int W = lab->W, 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 = 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)lab->L[i][j] / tmp[i][j]; + } + else + dcdamping (tmp, lab->L, 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 p1 = 1.0 - p2; + +#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; isharpening.method=="rld") { + deconvsharpening (lab, b2); + return; + } + + // Rest is UNSHARP MASK + if (params->sharpening.enabled==false || params->sharpening.amount<1 || lab->W<8 || lab->H<8) + return; + + int W = lab->W, H = lab->H; + float** b3; + if (params->sharpening.edgesonly) { + b3 = new float*[H]; + for (int i=0; i buffer(max(W,H)); + if (params->sharpening.edgesonly==false) { + + gaussHorizontal (lab->L, b2, buffer, W, H, params->sharpening.radius / scale); + gaussVertical (b2, b2, buffer, W, H, params->sharpening.radius / scale); + } + else { + bilateral (lab->L, (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 = lab->L; + if (params->sharpening.edgesonly) + base = b3; + + if (params->sharpening.halocontrol==false) { + #pragma omp for + 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 + ); + lab->L[i][j] = lab->L[i][j] + delta; + } + } + else + sharpenHaloCtrl (lab, b2, base, W, H); + + } // end parallel + + if (params->sharpening.edgesonly) { + for (int i=0; isharpening.halocontrol_amount) * 0.01f; + float sharpFac = params->sharpening.amount * 0.01f; + float** nL = base; + +#pragma omp parallel for if (multiThread) + for (int i=2; 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 = 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; + + 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; + } +#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) + 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 +#pragma omp parallel for private(offset, i,j) shared(LM) + for(j=0; jL[j][i]/327.68f;// adjust to 0.100 and to RT variables + } + +#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) + 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 +#pragma omp parallel for private(offset, i,j) shared(LM) + for(j=0; jsh_p[j][i]/327.68f;// adjust to 0.100 and to RT variables + } + +#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) + 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; + if (params->sharpening.edgesonly) { + b3 = 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) { + #pragma omp for + 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 + sharpenHaloCtrlcam (ncie, b2, base, W, H); + + } // end parallel + + if (params->sharpening.edgesonly) { + for (int i=0; isharpening.halocontrol_amount) * 0.01f; + float sharpFac = params->sharpening.amount * 0.01f; + float** nL = base; + +#pragma omp parallel for if (multiThread) + 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..b2896fe82 --- /dev/null +++ b/rtengine/iptransform.cc @@ -0,0 +1,906 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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" + +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 * 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(sin(val*M_PI/2), 3); + } else { + val = 1.0 - pow(cos(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(sin(val*M_PI/2), 3); + } else { + val = 1.0 - pow(cos(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 = atan2f(b, a); + float dist = sqrtf(a*a+b*b); + float dist_oe, dist_ie; + if (pcv.is_super_ellipse_mode) { + float dist_oe1 = pcv.oe1_a*pcv.oe1_b / powf(powf(pcv.oe1_b*cosf(angle), pcv.sep) + powf(pcv.oe1_a*sinf(angle), pcv.sep), 1.0/pcv.sep); + float dist_oe2 = pcv.oe2_a*pcv.oe2_b / powf(powf(pcv.oe2_b*cosf(angle), pcv.sep+2) + powf(pcv.oe2_a*sinf(angle), 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(pcv.oe_b*cosf(angle)*pcv.oe_b*cosf(angle) + pcv.oe_a*sinf(angle)*pcv.oe_a*sinf(angle)); + 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(cos(val*M_PI/2), 4); + } else { + val = 1 - pow(sin(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); + } + + #pragma omp parallel for if (multiThread) + for (int y=0; yheight; y++) { + double vig_y_d = (double) (y + cy) - vig_h2 ; + for (int x=0; xwidth; x++) { + double vig_x_d = (double) (x + cx) - vig_w2 ; + double r = sqrt(vig_x_d*vig_x_d + vig_y_d*vig_y_d); + double factor = 1.0; + if (applyVignetting) { + factor /= std::max(v + mul * tanh (b*(maxRadius-r) / maxRadius), 0.001); + } + 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 + #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()) + vignmul /= std::max(v + mul * tanh (b*(maxRadius-s*r2) / maxRadius), 0.001); + 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; + + // 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()) + vignmul /= std::max(v + mul * tanh (b*(maxRadius-s*r2) / maxRadius), 0.001); + 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..c7d01868a --- /dev/null +++ b/rtengine/ipvibrance.cc @@ -0,0 +1,455 @@ +/* + * 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 "calc_distort.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, bool needed) { + + if (needed && 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; + } + + int width = lab->W, 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, skinCurveIsSet); + if (dcurve) { + delete dcurve; + dcurve = NULL; + } + + +// skin_curve.dump("skin_curve"); + + float chromaPastel = float(params->vibrance.pastels) / 100.0f; + float chromaSatur = float(params->vibrance.saturated) / 100.0f; + float limitpastelsatur = static_cast(params->vibrance.psthreshold.value[ThresholdSelector::TS_TOPLEFT]) / 100.0f; + float transitionweighting = static_cast(params->vibrance.psthreshold.value[ThresholdSelector::TS_BOTTOMLEFT]) / 100.0f; + + bool highlight = params->toneCurve.hrenabled;//Get the value if "highlight reconstruction" is activated + bool protectskins = params->vibrance.protectskins; + bool avoidcolorshift = params->vibrance.avoidcolorshift; + + +#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) firstprivate(lab, width, height, chromaPastel, chromaSatur, highlight, limitpastelsatur, \ + transitionweighting, protectskins, avoidcolorshift) if (multiThread) +#endif +{ + + TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params->icm.working); + //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]} + }; + float sathue[5],sathue2[4];// adjust sat in function of hue + + const float p00=0.07f; + + // 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; + float maxdp=(limitpastelsatur-p00)/4.0f; + float maxds=(1.0-limitpastelsatur)/4.0f; + p0=p00+maxdp; + p1=p00+2.0f*maxdp; + p2=p00+3.0f*maxdp; + s0=limitpastelsatur + maxds; + s1=limitpastelsatur + 2.0f*maxds; + s2=limitpastelsatur + 3.0f*maxds; + + 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; + } + } + +#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, 10) + for (int i=0; iL[i][j]/327.68f; + float CC=sqrt(SQR(lab->a[i][j]/327.68f)+ SQR(lab->b[i][j]/327.68f)); + float HH=xatan2f(lab->b[i][j],lab->a[i][j]); + //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 satredu=1.0f; //reduct sat in function of skin + if(protectskins) { + Color::SkinSat (LL, HH, CC, satredu, 0);// 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 memChprov=CC; + float R, G, B; + +#ifdef _DEBUG + bool neg=false; + bool more_rgb=false; + //gamut control : Lab values are in gamut + Color::gamutLchonly(HH, 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, Lprov, Chprov, R, G, B, wip, highlight, 0.15f, 0.98f); +#endif + + float saturation=SAT(R,G,B); + //evaluate saturation with curve chroma +// saturation=(sat_curve[saturation*65535.0f])/65535.0f; + + // work on saturation + if(Chprov > 6.0f) { //protect gray and LUT Munsell + //pyramid to adjust saturation in function of saturation and hue (and Luminance) + 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; + } + + if(saturation>0.0f) { + 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 chromaPastel_a = (chromaPastel-chromamean)/(p2-limitpastelsatur); + float chromaPastel_b = chromaPastel-chromaPastel_a*p2; + float newchromaPastel = chromaPastel_a*saturation + chromaPastel_b; + chmodpastel = newchromaPastel*satredu*sathue[3]; + } + + // Saturated + if(saturation < s0 && saturation >=limitpastelsatur) { + float chromaSatur_a=(chromaSatur-chromamean)/(s0-limitpastelsatur); + float chromaSatur_b=chromaSatur-chromaSatur_a*s0; + 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; + } + } + } + + // Vibrance's Skin curve + if(skinCurveIsSet) { + 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 + + float ask=65535.0f/(skend-skbeg); + float bsk=-skbeg*ask; + + 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; + } + 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; + } + } + //transition hue + else if(HH>(skbeg-dhue) && HH<=skbeg && Chprov < (60.0f+dchr/2.0f)) { + 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; + } + else if(HH>=skend && HH<(skend+dhue) && Chprov < (60.0f+dchr/2.0f)) { + 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; + } + } // end skin hue + + //Munsell correction + float correctionHue=0.0f; + float correctlum; + + float aprovn,bprovn; + bool inGamut; + do { + inGamut=true; + if(avoidcolorshift) { + correctionHue=0.0f; + correctlum=0.0f; + +#ifdef _DEBUG + Color::AllMunsellLch(/*lumaMuns*/false, Lprov,Lprov,HH,Chprov,memChprov,correctionHue,correctlum, MunsDebugInfo); +#else + Color::AllMunsellLch(/*lumaMuns*/false, Lprov,Lprov,HH,Chprov,memChprov,correctionHue,correctlum); +#endif + } + float2 sincosval = xsincosf(HH+correctionHue); + 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.0f * Color::f2xyz(fxx)*Color::D50x; + // float yy_ = 65535.0f * Color::f2xyz(fyy); + float zz_ = 65535.0f * Color::f2xyz(fzz)*Color::D50z; + float yy_= (Lprov>Color::epskap) ? 65535.0*fyy*fyy*fyy : 65535.0*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/jdatasrc.cc b/rtengine/jdatasrc.cc new file mode 100644 index 000000000..92cc3492f --- /dev/null +++ b/rtengine/jdatasrc.cc @@ -0,0 +1,412 @@ +#include +#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..743582984 --- /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) { + + 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; idata, W*H*3*sizeof(float)); +} + +} diff --git a/rtengine/labimage.h b/rtengine/labimage.h new file mode 100644 index 000000000..6b024a435 --- /dev/null +++ b/rtengine/labimage.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 _LABIMAGE_H_ +#define _LABIMAGE_H_ + +namespace rtengine { + +class LabImage { +private: + bool fromImage; + +public: + int W, H; + float * data; + float** L; + float** a; + float** b; + + LabImage (int w, int h); + ~LabImage (); + + //Copies image data in Img into this instance. + void CopyFrom(LabImage *Img); +}; + +} +#endif diff --git a/rtengine/lcp.cc b/rtengine/lcp.cc new file mode 100644 index 000000000..51e19d7f0 --- /dev/null +++ b/rtengine/lcp.cc @@ -0,0 +1,681 @@ +/* +* 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 "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..7960f8925 --- /dev/null +++ b/rtengine/myfile.cc @@ -0,0 +1,355 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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; + + 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; + 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; + 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; + 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; +} diff --git a/rtengine/myfile.h b/rtengine/myfile.h new file mode 100644 index 000000000..473e440a2 --- /dev/null +++ b/rtengine/myfile.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 _MYFILE_ +#define _MYFILE_ + +#include +#include +#include +struct IMFILE { + int fd; + int pos; + int size; + char* data; + bool eof; +}; + +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) + return (unsigned char)f->data[f->pos++]; + f->eof = true; + return EOF; +} + +inline int getc (IMFILE* f) { + + if (f->possize) + return (unsigned char)f->data[f->pos++]; + f->eof = true; + return EOF; +} + +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; + 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..477e435ae --- /dev/null +++ b/rtengine/opthelper.h @@ -0,0 +1,63 @@ +//////////////////////////////////////////////////////////////// +// +// 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__ + #ifdef WIN32 + // 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__ + #ifdef WIN32 + // 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) + #else + #define RESTRICT + #define LIKELY(x) (x) + #define UNLIKELY(x) (x) + #endif +#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..2f136367b --- /dev/null +++ b/rtengine/procevents.h @@ -0,0 +1,281 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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, + EvPreProcessHotDeadPixel=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, +// EvLBWtoning=166, -- can be reused -- + 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, + + NUMOFEVENTS=250 +}; +} +#endif + diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc new file mode 100644 index 000000000..4562c5b8b --- /dev/null +++ b/rtengine/procparams.cc @@ -0,0 +1,2113 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 "rt_math.h" + +#include "safegtk.h" +#include "../rtgui/multilangmgr.h" +#include "procparams.h" +#include "../rtgui/version.h" +#include "../rtgui/ppversion.h" +#include "../rtgui/mydiagonalcurve.h" +#include "../rtgui/myflatcurve.h" +#include "safekeyfile.h" +#include "rawimage.h" +#include "../rtgui/ppversion.h" +#include "../rtgui/paramsedited.h" +#include "dcp.h" + +#define APPVERSION VERSION + +using namespace std; + +namespace rtengine { +namespace procparams { + +const char *RAWParams::methodstring[RAWParams::numMethods]={"amaze","igv","lmmse","eahd", "hphd", "vng4", "dcb", "ahd", "fast" }; + +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 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) const { + + 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; + } + 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; + } + 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.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.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.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); + + //Save edgePreservingDecompositionUI. + if (!pedited || pedited->edgePreservingDecompositionUI.enabled) keyFile.set_boolean ("EPD", "Enabled", edgePreservingDecompositionUI.enabled); + if (!pedited || pedited->edgePreservingDecompositionUI.Strength) keyFile.set_double ("EPD", "Strength", edgePreservingDecompositionUI.Strength); + if (!pedited || pedited->edgePreservingDecompositionUI.EdgeStopping) keyFile.set_double ("EPD", "EdgeStopping", edgePreservingDecompositionUI.EdgeStopping); + if (!pedited || pedited->edgePreservingDecompositionUI.Scale) keyFile.set_double ("EPD", "Scale", edgePreservingDecompositionUI.Scale); + if (!pedited || pedited->edgePreservingDecompositionUI.ReweightingIterates) keyFile.set_integer ("EPD", "ReweightingIterates", edgePreservingDecompositionUI.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); + + // 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.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 directional pyramid equalizer parameters + if (!pedited || pedited->dirpyrequalizer.enabled) keyFile.set_boolean ("Directional Pyramid Equalizer", "Enabled", dirpyrequalizer.enabled); + for(int i = 0; i < 5; 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); + + // save hsv equalizer 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); + } + + + 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 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.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.hotDeadPixelFilter) keyFile.set_boolean ("RAW", "HotDeadPixels", raw.hotdeadpix_filt ); + if (!pedited || pedited->raw.hotDeadPixelThresh) keyFile.set_integer ("RAW", "HotDeadPixelThresh", raw.hotdeadpix_thresh ); + if (!pedited || pedited->raw.linenoise) keyFile.set_integer ("RAW", "LineDenoise", raw.linenoise); + if (!pedited || pedited->raw.greenEq) keyFile.set_integer ("RAW", "GreenEqThreshold", raw.greenthresh); + if (!pedited || pedited->raw.ccSteps) keyFile.set_integer ("RAW", "CcSteps", raw.ccSteps); + if (!pedited || pedited->raw.dmethod) keyFile.set_string ("RAW", "Method", raw.dmethod ); + if (!pedited || pedited->raw.dcbIterations) keyFile.set_integer ("RAW", "DCBIterations", raw.dcb_iterations ); + if (!pedited || pedited->raw.dcbEnhance) keyFile.set_boolean ("RAW", "DCBEnhance", raw.dcb_enhance ); + if (!pedited || pedited->raw.lmmseIterations) keyFile.set_integer ("RAW", "LMMSEIterations", raw.lmmse_iterations ); + + //if (!pedited || pedited->raw.allEnhance) keyFile.set_boolean ("RAW", "ALLEnhance", raw.all_enhance ); + + // 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 ); + if (!pedited || pedited->raw.exBlackzero) keyFile.set_double ("RAW", "PreBlackzero", raw.blackzero ); + if (!pedited || pedited->raw.exBlackone) keyFile.set_double ("RAW", "PreBlackone", raw.blackone ); + if (!pedited || pedited->raw.exBlacktwo) keyFile.set_double ("RAW", "PreBlacktwo", raw.blacktwo ); + if (!pedited || pedited->raw.exBlackthree) keyFile.set_double ("RAW", "PreBlackthree", raw.blackthree ); + if (!pedited || pedited->raw.exTwoGreen) keyFile.set_boolean ("RAW", "PreTwoGreen", raw.twogreen ); + + // 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) { + + 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; + 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; + 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", "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", "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", "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; } +} + + //Load EPD. +if (keyFile.has_group ("EPD")) { + if(keyFile.has_key("EPD", "Enabled")) { edgePreservingDecompositionUI.enabled = keyFile.get_boolean ("EPD", "Enabled"); if (pedited) pedited->edgePreservingDecompositionUI.enabled = true; } + if(keyFile.has_key("EPD", "Strength")) { edgePreservingDecompositionUI.Strength = keyFile.get_double ("EPD", "Strength"); if (pedited) pedited->edgePreservingDecompositionUI.Strength = true; } + if(keyFile.has_key("EPD", "EdgeStopping")) { edgePreservingDecompositionUI.EdgeStopping = keyFile.get_double ("EPD", "EdgeStopping"); if (pedited) pedited->edgePreservingDecompositionUI.EdgeStopping = true; } + if(keyFile.has_key("EPD", "Scale")) { edgePreservingDecompositionUI.Scale = keyFile.get_double ("EPD", "Scale"); if (pedited) pedited->edgePreservingDecompositionUI.Scale = true; } + if(keyFile.has_key("EPD", "ReweightingIterates")) { edgePreservingDecompositionUI.ReweightingIterates = keyFile.get_integer ("EPD", "ReweightingIterates"); if (pedited) pedited->edgePreservingDecompositionUI.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 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", "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 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 (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 equalizer + dedicated threshold parameter + for(int i = 0; i < 5; 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; } + } +} + + // load HSV equalizer 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 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", "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; } + if (keyFile.has_key ("RAW", "HotDeadPixels")) { raw.hotdeadpix_filt = keyFile.get_boolean ("RAW", "HotDeadPixels" ); if (pedited) pedited->raw.hotDeadPixelFilter = 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", "LineDenoise")) { raw.linenoise = keyFile.get_integer ("RAW", "LineDenoise" ); if (pedited) pedited->raw.linenoise = true; } + if (keyFile.has_key ("RAW", "GreenEqThreshold")) { raw.greenthresh= keyFile.get_integer ("RAW", "GreenEqThreshold"); if (pedited) pedited->raw.greenEq = true; } + if (keyFile.has_key ("RAW", "CcSteps")) { raw.ccSteps = keyFile.get_integer ("RAW", "CcSteps"); if (pedited) pedited->raw.ccSteps = true; } + if (keyFile.has_key ("RAW", "Method")) { raw.dmethod = keyFile.get_string ("RAW", "Method"); if (pedited) pedited->raw.dmethod = true; } + if (keyFile.has_key ("RAW", "DCBIterations")) { raw.dcb_iterations = keyFile.get_integer("RAW", "DCBIterations"); if (pedited) pedited->raw.dcbIterations = true; } + if (keyFile.has_key ("RAW", "DCBEnhance")) { raw.dcb_enhance =keyFile.get_boolean("RAW", "DCBEnhance"); if (pedited) pedited->raw.dcbEnhance = true; } + if (keyFile.has_key ("RAW", "LMMSEIterations")) { raw.lmmse_iterations = keyFile.get_integer("RAW", "LMMSEIterations"); if (pedited) pedited->raw.lmmseIterations = true; } + //if (keyFile.has_key ("RAW", "ALLEnhance")) { raw.all_enhance =keyFile.get_boolean("RAW", "ALLEnhance"); if (pedited) pedited->raw.allEnhance = 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 (keyFile.has_key ("RAW", "PreBlackzero")) { raw.blackzero =keyFile.get_double("RAW", "PreBlackzero"); if (pedited) pedited->raw.exBlackzero = true; } + if (keyFile.has_key ("RAW", "PreBlackone")) { raw.blackone =keyFile.get_double("RAW", "PreBlackone"); if (pedited) pedited->raw.exBlackone = true; } + if (keyFile.has_key ("RAW", "PreBlacktwo")) { raw.blacktwo =keyFile.get_double("RAW", "PreBlacktwo"); if (pedited) pedited->raw.exBlacktwo = true; } + if (keyFile.has_key ("RAW", "PreBlackthree")) { raw.blackthree =keyFile.get_double("RAW", "PreBlackthree"); if (pedited) pedited->raw.exBlackthree = true; } + if (keyFile.has_key ("RAW", "PreTwoGreen")) { raw.twogreen =keyFile.get_boolean("RAW", "PreTwoGreen"); if (pedited) pedited->raw.exTwoGreen = 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 DirPyrEqualizerParams & a, const DirPyrEqualizerParams & b) { + if(a.enabled != b.enabled) + return false; + + for(int i = 0; i < 5; 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 + && 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.perform == other.dirpyrDenoise.perform + && dirpyrDenoise.luma == other.dirpyrDenoise.luma + && dirpyrDenoise.Ldetail == other.dirpyrDenoise.Ldetail + && dirpyrDenoise.chroma == other.dirpyrDenoise.chroma + && dirpyrDenoise.dmethod == other.dirpyrDenoise.dmethod + && dirpyrDenoise.redchro == other.dirpyrDenoise.redchro + && dirpyrDenoise.bluechro == other.dirpyrDenoise.bluechro + && dirpyrDenoise.gamma == other.dirpyrDenoise.gamma + && edgePreservingDecompositionUI.enabled == other.edgePreservingDecompositionUI.enabled + && edgePreservingDecompositionUI.Strength == other.edgePreservingDecompositionUI.Strength + && edgePreservingDecompositionUI.EdgeStopping == other.edgePreservingDecompositionUI.EdgeStopping + && edgePreservingDecompositionUI.Scale == other.edgePreservingDecompositionUI.Scale + && edgePreservingDecompositionUI.ReweightingIterates == other.edgePreservingDecompositionUI.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 + && 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.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.dcb_enhance == other.raw.dcb_enhance + && raw.dcb_iterations == other.raw.dcb_iterations + && raw.ccSteps == other.raw.ccSteps + && raw.ca_autocorrect == other.raw.ca_autocorrect + && raw.cared == other.raw.cared + && raw.cablue == other.raw.cablue + && raw.hotdeadpix_filt == other.raw.hotdeadpix_filt + && raw.hotdeadpix_thresh == other.raw.hotdeadpix_thresh + && raw.dmethod == other.raw.dmethod + && raw.greenthresh == other.raw.greenthresh + && raw.linenoise == other.raw.linenoise + && icm.input == other.icm.input + && icm.toneCurve == other.icm.toneCurve + && 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 + && dirpyrequalizer == other.dirpyrequalizer + && hsvequalizer.hcurve == other.hsvequalizer.hcurve + && hsvequalizer.scurve == other.hsvequalizer.scurve + && hsvequalizer.vcurve == other.hsvequalizer.vcurve + && rgbCurves.rcurve == other.rgbCurves.rcurve + && rgbCurves.gcurve == other.rgbCurves.gcurve + && rgbCurves.bcurve == other.rgbCurves.bcurve + && exif==other.exif + && iptc==other.iptc + && raw.expos==other.raw.expos + && raw.preser==other.raw.preser + && raw.preser==other.raw.preser + && raw.blackzero==other.raw.blackzero + && raw.blackone==other.raw.blackone + && raw.blacktwo==other.raw.blacktwo + && raw.blackthree==other.raw.blackthree + && raw.twogreen==other.raw.twogreen; + +} + +bool ProcParams::operator!= (const ProcParams& other) { + + return !(*this==other); +} + +PartialProfile::PartialProfile(bool createInstance) { + if (createInstance) { + pparams = new ProcParams(); + pedited = new ParamsEdited(); + } + 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(); + 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..656180761 --- /dev/null +++ b/rtengine/procparams.h @@ -0,0 +1,956 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 +#include "LUT.h" + +class ParamsEdited; + +namespace rtengine { +namespace procparams { + +template +class Threshold { + public: + T value[4]; + + protected: + bool initEq1; + bool _isDouble; +#ifndef NDEBUG + unsigned int part[5]; +#endif + + public: + Threshold (T val1, T val2, bool startAtOne) { + initEq1 = startAtOne; + value[0] = val1; + value[1] = val2; + value[2] = T(0); + value[3] = T(0); + _isDouble = false; + } + + Threshold (T val1, T val2, T val3, T val4, bool startAtOne) { + initEq1 = startAtOne; + value[0] = val1; + value[1] = val2; + value[2] = val3; + value[3] = val4; + _isDouble = true; + } + + // for convenience, since 'values' is public + void setValues(T val1, T val2) { + value[0] = val1; + value[1] = val2; + } + + // for convenience, since 'values' is public + void setValues(T val1, T val2, T val3, T val4) { + value[0] = val1; + value[1] = val2; + value[2] = val3; + value[3] = val4; + } + + 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 + }; + + 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 + + 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 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: + bool enabled; + bool enhance; + + bool perform; + double luma; + double Ldetail; + double chroma; + double redchro; + double bluechro; + double gamma; + Glib::ustring dmethod; +}; + +//EPD related parameters. +class EPDParams{ + public: + bool enabled; + double Strength; + 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; + + 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; +}; + +/** + * 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; +}; + +/** + * 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; + + 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 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; + +}; + +/** + * Typedef for representing a key/value for the exif metadata information + */ +typedef std::map ExifPairs; + +/** + * The IPTC key/value pairs + */ +typedef std::map > IPTCPairs; + +/** +* Directional pyramid equalizer params +*/ +class DirPyrEqualizerParams { + + public: + bool enabled; + double mult[5]; + double threshold; +}; + +/** + * HSV equalizer params + */ +class HSVEqualizerParams { + + public: + std::vector hcurve; + std::vector scurve; + std::vector vcurve; + +}; + + + +/** + * Parameters for RAW demosaicing + */ +class RAWParams { + + 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, + numMethods }; // This MUST be the last enum + + static const char *methodstring[numMethods]; + + 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 ca_autocorrect; + double cared; + double cablue; + + // exposure before interpolation + double expos; + double preser; + double blackzero; + double blackone; + double blacktwo; + double blackthree; + bool twogreen; + bool hotdeadpix_filt; + int hotdeadpix_thresh; + int linenoise; + int greenthresh; + int ccSteps; + Glib::ustring dmethod; + int dcb_iterations; + int lmmse_iterations; + + bool dcb_enhance; + //bool all_enhance; +}; + +/** + * 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 + SharpeningParams sharpening; ///< Sharpening parameters + 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 edgePreservingDecompositionUI; + 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 + DirPyrEqualizerParams dirpyrequalizer; ///< directional pyramid equalizer parameters + HSVEqualizerParams hsvequalizer; ///< hsv equalizer 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) const; + /** + * 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); + 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..485be7411 --- /dev/null +++ b/rtengine/rawimage.cc @@ -0,0 +1,571 @@ +/* + * This file is part of RawTherapee. + * + * Created on: 20/nov/2010 + */ + +#include "rawimage.h" +#include "settings.h" +#include "colortemp.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(data){ delete [] data; data=NULL;} + if(profile_data){ delete [] profile_data; profile_data=NULL;} +} + +/* 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(); + int val; + double dsum[8], dmin, dmax; + + 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); + 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; + + 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(0); + } + } + } + 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) - this->get_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) +{ + 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; + + 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; + 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; + + 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)(); + + 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); + 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 = w; + } + if (h < 0) { + iheight += h; + iheight -= top_margin; + height += h; + height -= top_margin; + } else if (h > 0) { + iheight = 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; + } + + // 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] = 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 (black_c4[0] == -1) { + // RT constants not set, bring in the DCRAW single channel black constant + for (int c=0; c < 4; c++) black_c4[c] = black; + } 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; + } + + return 0; +} + +unsigned short** RawImage::compress_image() +{ + if( !image ) + return NULL; + if (filters) { + if (!allocation) { + allocation = new unsigned short[height * width]; + data = new unsigned short*[height]; + for (int i = 0; i < height; i++) + data[i] = allocation + i * width; + } + } else { + if (!allocation) { + allocation = new unsigned short[3 * height * width]; + data = new unsigned short*[height]; + for (int i = 0; i < height; i++) + data[i] = allocation + 3 * i * width; + } + } + + // copy pixel raw data: the compressed format earns space + if (filters != 0) { + #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 { + #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 * width + col][0]; + this->data[row][3 * col + 1] = image[row * width + col][1]; + this->data[row][3 * col + 2] = image[row * width + col][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 ); +} + +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 } }, + + + { "Panasonic DMC-FZ150", 143, 0xfff, /* RT */ + { 10435,-3208,-72,-2293,10506,2067,-486,1725,4682 } }, + { "Panasonic DMC-G10", 15, 0xf3c, /* RT - Colin Walker */ + { 8310,-1811,-960,-4941,12990,2151,-1378,2468,6860 } }, + { "Panasonic DMC-G1", 15, 0xf94, /* RT - Colin Walker*/ + { 7477,-1615,-651,-5016,12769,2506,-1380,2475,7240 } }, + { "Panasonic DMC-G2", 15, 0xf3c, /* RT - Colin Walker */ + { 8310,-1811,-960,-4941,12990,2151,-1378,2468,6860 } }, + { "Panasonic DMC-G3", 143, 0xfff, /* RT - Colin Walker */ + { 6051,-1406,-671,-4015,11505,2868,-1654,2667,6219 } }, + { "Panasonic DMC-G5", 143, 0xfff, /* RT */ + { 7122,-2092,-419,-4643,11769,3283,-1363,2413,5944 } }, + { "Panasonic DMC-GF1", 15, 0xf92, /* RT - Colin Walker */ + { 7863,-2080,-668,-4623,12331,2578,-1020,2066,7266 } }, + { "Panasonic DMC-GF2", 143, 0xfff, /* RT - Colin Walker */ + { 7694,-1791,-745,-4917,12818,2332,-1221,2322,7197 } }, + { "Panasonic DMC-GF3", 143, 0xfff, /* RT - Colin Walker */ + { 8074,-1846,-861,-5026,12999,2239,-1320,2375,7422 } }, + { "Panasonic DMC-GH1", 15, 0xf92, /* RT - Colin Walker */ + { 6360,-1557,-375,-4201,11504,3086,-1378,2518,5843 } }, + { "Panasonic DMC-GH2", 15, 0xf95, /* RT - Colin Walker */ +// { 6855,-1765,-456,-4223,11600,2996,-1450,2602,5761 } }, disabled + { 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 DSLR-A700", 126 << dcraw_arw2_scaling_bugfix_shift, -1, /* RT */ + { 6509,-1333,-137,-6171,13621,2824,-1490,2226,6952 } }, + { "Sony DSLR-A900", 128 << dcraw_arw2_scaling_bugfix_shift, -1, /* RT */ + { 5715,-1433,-410,-5603,12937,2989,-644,1247,8372 } }, + { "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..0a4af7d4a --- /dev/null +++ b/rtengine/rawimage.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 __RAWIMAGE_H +#define __RAWIMAGE_H + +#include +#include +#include "dcraw.h" + +namespace rtengine { + +struct badPix +{ + int x; + int y; + badPix( int xc, int 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::list &bp) + { + int totSet=0; + for(std::list::iterator iter = bp.begin(); iter != bp.end(); iter++,totSet++) + set( iter->x,iter->y); + return totSet; + } + + 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); + 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; } + unsigned short** compress_image(); // revert to compressed pixels format and release image data + unsigned short** 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 + unsigned short* allocation; // pointer to allocated memory + int maximum_c4[4]; + +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_FujiWidth() const { return fuji_width; } + bool isBayer() const { return filters!=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;} +public: + // dcraw functions + void scale_colors(){ 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); } +}; + +} + +#endif // __RAWIMAGE_H diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc new file mode 100644 index 000000000..19c964ce0 --- /dev/null +++ b/rtengine/rawimagesource.cc @@ -0,0 +1,2934 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 + +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; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +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]) +{ + float pre_mul[4]; + for (int c = 0; c < 4; c++) { + pre_mul[c] = pre_mul_[c]; // G2 == G1 + } + if (pre_mul[3] == 0) { + pre_mul[3] = pre_mul[1]; + } + 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; + 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]; + float gain = calculate_scale_mul(new_scale_mul, new_pre_mul, c_white, cblacksom); + 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; + + hlmax[0]=chmax[0]*rm*area; + hlmax[1]=chmax[1]*gm*area; + hlmax[2]=chmax[2]*bm*area; + + +#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->isBayer()) { + 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; mmaxx-skip) jx=maxx-skip-1; + float rtot,gtot,btot; + rtot=gtot=btot=0; + for (int m=0; mwidth%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->isBayer() && pp.skip==1) + processFalseColorCorrection (image, raw.ccSteps); + // *** colorSpaceConversion was here *** + //colorSpaceConversion (image, cmp, raw, embProfile, camProfile, xyz_cam, (static_cast(getMetaData()))->getCamera()); +} + +void RawImageSource::convertColorSpace(Imagefloat* image, ColorManagementParams cmp, ColorTemp &wb, RAWParams raw) { + colorSpaceConversion (image, cmp, wb, raw, embProfile, camProfile, imatrices.xyz_cam, (static_cast(getMetaData()))->getCamera()); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +/* cfaCleanFromMap: correct raw pixels looking at the bitmap + * takes into consideration if there are multiple bad pixels in the neighborhood + */ +int RawImageSource::cfaCleanFromMap( PixelsMap &bitmapBads ) +{ + float eps=1.0; + int counter=0; + for( int row = 2; row < H-2; row++ ){ + for(int col = 2; col 0.0){ + rawData[row][col]= wtdsum / norm;//gradient weighted average + counter++; + } else { + if (tot > 0.1) rawData[row][col] = sum/tot;//backup plan -- simple average + } + } + } + return counter; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +/* 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::findHotDeadPixel( PixelsMap &bpMap, float thresh) +{ + // 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] = fabs(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]; + 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 += cfablur[mmmWpnn]; + } + } + if (pixdev * ((bottom-top+1)*(right-left+1)-1) > thresh*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 (); + if (errCode) return errCode; + + ri->compress_image(); + if (plistener) { + plistener->setProgress (0.8); + } +/***** 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->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 µsec\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()); + } + //copyOriginalPixels(ri, rid); + + //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 + + + + PixelsMap bitmapBads(W,H); + int totBP=0; // Hold count of bad pixels to correct + + // Always correct camera badpixels + std::list *bp = dfm.getBadPixels( ri->get_maker(), ri->get_model(), std::string("") ); + 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) { + 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 ( raw.hotdeadpix_filt>0 ) { + if (plistener) { + plistener->setProgressStr ("Hot/Dead Pixel Filter..."); + plistener->setProgress (0.0); + } + float varthresh = (20.0*((float)raw.hotdeadpix_thresh/100.0) + 1.0 ); + int nFound =findHotDeadPixel( bitmapBads, varthresh ); + totBP += nFound; + if( settings->verbose && nFound>0){ + printf( "Correcting %d hot/dead pixels found inside image\n",nFound ); + } + } + if( totBP ) + cfaCleanFromMap( bitmapBads ); + + // check if it is an olympus E camera, if yes, compute G channel pre-compensation factors + if ( raw.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.dmethod != RAWParams::methodstring[ RAWParams::vng4] && ri->isBayer()) ) { + // 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 ( raw.greenthresh >0) { + if (plistener) { + plistener->setProgressStr ("Green equilibrate..."); + plistener->setProgress (0.0); + } + green_equilibrate(0.01*(raw.greenthresh)); + } + + + if ( raw.linenoise >0 ) { + if (plistener) { + plistener->setProgressStr ("Line Denoise..."); + plistener->setProgress (0.0); + } + + cfa_linedn(0.00002*(raw.linenoise)); + } + + if ( raw.ca_autocorrect || fabs(raw.cared)>0.001 || fabs(raw.cablue)>0.001 ) { + 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) +{ + if (ri->isBayer()) { + MyTime t1,t2; + t1.set(); + if ( raw.dmethod == RAWParams::methodstring[RAWParams::hphd] ) + hphd_demosaic (); + else if (raw.dmethod == RAWParams::methodstring[RAWParams::vng4] ) + vng4_demosaic (); + else if (raw.dmethod == RAWParams::methodstring[RAWParams::ahd] ) + ahd_demosaic (0,0,W,H); + else if (raw.dmethod == RAWParams::methodstring[RAWParams::amaze] ) + amaze_demosaic_RT (0,0,W,H); + else if (raw.dmethod == RAWParams::methodstring[RAWParams::dcb] ) + dcb_demosaic(raw.dcb_iterations, raw.dcb_enhance); + else if (raw.dmethod == RAWParams::methodstring[RAWParams::eahd]) + eahd_demosaic (); + else if (raw.dmethod == RAWParams::methodstring[RAWParams::igv]) + igv_interpolate(W,H); + else if (raw.dmethod == RAWParams::methodstring[RAWParams::lmmse]) + lmmse_interpolate_omp(W,H,raw.lmmse_iterations); + else if (raw.dmethod == RAWParams::methodstring[RAWParams::fast] ) + fast_demosaic (0,0,W,H); + //nodemosaic();//for testing + else + nodemosaic(); + t2.set(); + if( settings->verbose ) + printf("Demosaicing: %s - %d usec\n",raw.dmethod.c_str(), t2.etime(t1)); + + //if (raw.all_enhance) refinement_lassus(); + + rgbSourceModified = false; + } +} + +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 ) +{ + //color propagation highlight recovery + if (hrp.hrenabled && hrp.method=="Color"){ + if (settings->verbose) printf ("Applying Highlight Recovery: Color propagation...\n"); + HLRecovery_inpaint (red,green,blue); + rgbSourceModified = true; + } + else{ + rgbSourceModified = false; + } +} + + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +/* 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->isBayer()) { + 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++) { + 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); + } + } + }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()) { + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + float (*cfablur); + cfablur = (float (*)) calloc (H*W, sizeof *cfablur); +//#define BS 32 + int BS = raw.ff_BlurRadius; + if (BS&1) BS++; + + //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); + + float refcolor[2][2],vignettecorr; + //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]); + } + + for (int m=0; m<2; m++) + for (int n=0; n<2; n++) { + for (int row = 0; row+m < H; row+=2) + for (int col = 0; col+n < W; col+=2) { + int c = FC(row, col); + int c4 = ( c == 1 && !(row&1) ) ? 3 : c; + 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]; + } + } + + 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 + + float vlinecorr, hlinecorr; + + for (int m=0; m<2; m++) + for (int n=0; n<2; n++) { + for (int row = 0; row+m < H; row+=2) + for (int col = 0; col+n < W; col+=2) { + int c = FC(row, col); + int c4 = ( c == 1 && !(row&1) ) ? 3 : c; + hlinecorr = (max(1e-5f,cfablur[(row+m)*W+col+n]-black[c4])/max(1e-5f,cfablur1[(row+m)*W+col+n]-black[c4]) ); + 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]); + } + } + free (cfablur1); + free (cfablur2); + } + + free (cfablur); + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +//#undef BS + + + } // flatfield + } 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); + rawData[row][3*col+1] = max(src->data[row][3*col+1]+black[c4] - riDark->data[row][3*col+1], 0); + rawData[row][3*col+2] = max(src->data[row][3*col+2]+black[c4] - riDark->data[row][3*col+2], 0); + } + } + } 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]; + } + } + } + } +} + +void RawImageSource::cfaboxblur(RawImage *riFlatFile, float* cfablur, int boxH, int boxW ) { + + float (*cfatmp); + cfatmp = (float (*)) calloc (H*W, sizeof *cfatmp); + float hotdeadthresh = 0.5; + + 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]) { + cfatmp[i*W+j] = median; + } else { + cfatmp[i*W+j] = riFlatFile->data[i][j]; + } + + } + } + + //box blur cfa image; box size = BS + //horizontal blur + 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; colisBayer() ){ +#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{ +#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, float rawWhitePoint, 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, rawWhitePoint, cmp.toneCurve); + 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,"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\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* pre_mul, const RAWParams &raw, 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; + + +#pragma omp parallel for + 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 + { float pre_mul[4]; + for(int c=0;c<4;c++) pre_mul[c]=ri->get_pre_mul(c); + HLRecovery_blend(red, green, blue, width, 65535.0, pre_mul, raw, 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; iisBayer()) { + 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 { + 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(); + 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) }; + +#pragma omp parallel +{ + LUTu tmphistRedRaw( 256 ); + LUTu tmphistGreenRaw( 256 ); + LUTu tmphistBlueRaw( 256 ); + tmphistRedRaw.clear(); + tmphistGreenRaw.clear(); + tmphistBlueRaw.clear(); + +#pragma omp for nowait + for (int i=border; iisBayer()) { + for (int j=start; jdata[i][j]-(cblacksom[c4]/*+black_lev[c4]*/)))); + + switch (c) { + case 0: tmphistRedRaw[idx>>8]++; break; + case 1: tmphistGreenRaw[idx>>8]++; break; + case 2: tmphistBlueRaw[idx>>8]++; break; + } + } + } else { + for (int j=start; jdata[i][3*j+c]-cblacksom[c]))); + + switch (c) { + case 0: tmphistRedRaw[idx>>8]++; break; + case 1: tmphistGreenRaw[idx>>8]++; break; + case 2: tmphistBlueRaw[idx>>8]++; break; + } + } + } + } + } +#pragma omp critical +{ + for(int i=0;i<256;i++){ + histRedRaw[i] += tmphistRedRaw[i]; + histGreenRaw[i] += tmphistGreenRaw[i]; + histBlueRaw[i] += tmphistBlueRaw[i]; + } +} +} + + // since there are twice as many greens, correct for it + if (ri->isBayer()) for (int i=0;i<256;i++) histGreenRaw[i]>>=1; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +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 (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; jisBayer()) { + 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->isBayer()) { + 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->isBayer()) { + 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 && xv=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..adb356854 --- /dev/null +++ b/rtengine/rawimagesource.h @@ -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 . + */ +#ifndef _RAWIMAGESOURCE_ +#define _RAWIMAGESOURCE_ + +#include "imagesource.h" +#include +#include "dcp.h" +#include "array2D.h" +#include "curves.h" +#include +#include "color.h" +#include "iimage.h" +#include "../rtgui/cacheimagedata.h" +#include "../rtgui/threadutils.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 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); + 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); + + void convertColorSpace(Imagefloat* image, ColorManagementParams cmp, ColorTemp &wb, RAWParams raw); + //static void colorSpaceConversion16 (Image16* im, ColorManagementParams cmp, cmsHPROFILE embedded, cmsHPROFILE camprofile, double cam[3][3], std::string camName); + static void colorSpaceConversion (Imagefloat* im, ColorManagementParams cmp, ColorTemp &wb, cmsHPROFILE embedded, cmsHPROFILE camprofile, double cam[3][3], std::string camName) { + colorSpaceConversion (im, cmp, wb, 0.0f, embedded, camprofile, cam, camName); + } + static void colorSpaceConversion (Imagefloat* im, ColorManagementParams cmp, ColorTemp &wb, RAWParams raw, cmsHPROFILE embedded, cmsHPROFILE camprofile, double cam[3][3], std::string camName) { + colorSpaceConversion (im, cmp, wb, float(raw.expos), 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, float & max, 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* pre_mul, const RAWParams &raw, 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, double r_mul, double g_mul, double 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 cfaCleanFromMap( PixelsMap &bitmapBads ); + int findHotDeadPixel( PixelsMap &bpMap, float thresh); + + void cfa_linedn (float linenoiselevel);//Emil's line denoise + void cfa_tile_denoise (fftwf_complex * fcfablox, int vblk, int hblk, int numblox_H, int numblox_W, float noisevar, float * rolloff ); + void cfa_output_tile_row (float *cfabloxrow, float ** cfahipassdn, float ** tilemask_out, int height, int width, int top, int blkrad); + + void green_equilibrate (float greenthresh);//Emil's green equilibration + + void nodemosaic(); + 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 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..d24c3040c --- /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 + int 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 + int 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..ae2eb6933 --- /dev/null +++ b/rtengine/refreshmap.cc @@ -0,0 +1,279 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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, +ALL, // 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, // EvPreProcessHotDeadPixel +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 +NONE, // --unused--, +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 + + +//LUMINANCECURVE // EvCATsharpcie + + +}; + diff --git a/rtengine/refreshmap.h b/rtengine/refreshmap.h new file mode 100644 index 000000000..ba914e77d --- /dev/null +++ b/rtengine/refreshmap.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 __REFRESHMAP__ +#define __REFRESHMAP__ + +#include + +// Use M_VOID is you wish to update the proc params without updating the preview at all ! +#define M_VOID (1<<15) +// Use M_MINUPDATE if you 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..139c98fbe --- /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(1),std::min(a,_Tp(0))); + } + + 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..a973703a3 --- /dev/null +++ b/rtengine/rtengine.h @@ -0,0 +1,440 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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. + * + */ + + +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; } + }; + + /** 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 AutoBWListener { + public : + virtual ~AutoBWListener() {} + virtual void BWChanged (double redbw, double greenbw, double bluebw) {} + + }; + + + /** 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; + + /** Creates and returns a Crop instance that acts as a window on the image */ + virtual DetailedCrop* createCrop () =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) =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 ~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); + +/** 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..2af226f54 --- /dev/null +++ b/rtengine/rtthumbnail.cc @@ -0,0 +1,1471 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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" + +extern Options options; + +namespace rtengine { + +Thumbnail* Thumbnail::loadFromImage (const Glib::ustring& fname, int &w, int &h, int fixwh, double wbEq) { + + 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 (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; + 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) +{ + 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("loadfromMemory: error\n"); + 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 (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; + 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; + } + } + + 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 + 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->isBayer()) { + // 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 { + 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) = 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; + } + 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; + } + + // 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; + } + for (int j = start; j < end; j++) { + 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++; + } + } + } + + 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) { +} + +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) + RawImageSource::colorSpaceConversion (baseImg, params.icm, currWB, 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, gamma); + + // 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 rCurve (65536); + LUTf gCurve (65536); + LUTf bCurve (65536); + + LUTu dummy; + + ToneCurve customToneCurve1, customToneCurve2; + ColorAppearance customColCurve1; + ColorAppearance customColCurve2; + ColorAppearance customColCurve3; + ToneCurve customToneCurvebw1; + ToneCurve customToneCurvebw2; + + ipf.g = gamma; + ipf.iGamma = true; + CurveFactory::complexCurve (expcomp, 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); + + LabImage* labView = new LabImage (fw,fh); + CieImage* cieView = new CieImage (fw,fh); + + CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, hist16, dummy, customToneCurvebw1, customToneCurvebw2, 16); + + double rrm, ggm, bbm; + float autor, autog, autob; + autor = autog = autob = -9000.f; // This will ask to compute the "auto" values for the B&W tool + ipf.rgbProc (baseImg, labView, curve1, curve2, curve, shmap, params.toneCurve.saturation, rCurve, gCurve, bCurve, customToneCurve1, customToneCurve2, customToneCurvebw1, customToneCurvebw2,rrm, ggm, bbm, autor, autog, autob, expcomp, hlcompr, hlcomprthresh); + + 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 (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 (1,labView, labView, curve1, curve2, satcurve,lhskcurve, clcurve, curve, utili, autili, butili, ccutili,cclutili, clcutili, dummy, dummy, dummy, dummy); + + ipf.vibrance(labView); + int begh = 0, endh = labView->H; + + 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){ + float** buffer = new float*[fh]; + for (int i=0; i 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; + ipf.ciecam_02float (cieView, adap, begh, endh, 1, 2, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 6, (float**)buffer, execsharp, d); + for (int i=0; iwidth / 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 = 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; + if (params.coarse.hflip) tr |= TR_HFLIP; + if (params.coarse.vflip) tr |= TR_VFLIP; + + // 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) { + + 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; +} + +} diff --git a/rtengine/rtthumbnail.h b/rtengine/rtthumbnail.h new file mode 100644 index 000000000..669b33083 --- /dev/null +++ b/rtengine/rtthumbnail.h @@ -0,0 +1,158 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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); + 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); + 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); + + + // 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..f4bf5c804 --- /dev/null +++ b/rtengine/safegtk.cc @@ -0,0 +1,495 @@ +/* + * 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::ConvertError& e) { + utf8_str = Glib::convert_with_fallback(src, "UTF8", "LATIN1","?"); + } +#else + { + std::auto_ptr error; + utf8_str = locale_to_utf8(src, error); + if (error.get()) + utf8_str = Glib::convert_with_fallback(src, "UTF8", "LATIN1","?", 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::ConvertError& e) { + utf8_str = Glib::convert_with_fallback(src, "UTF8", "LATIN1","?"); + } +#else + { + std::auto_ptr error; + utf8_str = locale_to_utf8(src, error); + if (error.get()) + utf8_str = Glib::convert_with_fallback(src, "UTF8", "LATIN1","?", 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::ConvertError& e) { + //str = Glib::convert_with_fallback(utf8_str, "LATIN1", "UTF8", "?"); + } +#else + { + std::auto_ptr error; + str = Glib::locale_from_utf8(utf8_str, error); + /*if (error.get()) + {str = Glib::convert_with_fallback(utf8_str, "LATIN1", "UTF8", "?", 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 +} + +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_picture_dir() == path; +} +#endif diff --git a/rtengine/safegtk.h b/rtengine/safegtk.h new file mode 100644 index 000000000..95ebddbd5 --- /dev/null +++ b/rtengine/safegtk.h @@ -0,0 +1,51 @@ +#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 +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..005c83a3f --- /dev/null +++ b/rtengine/safekeyfile.h @@ -0,0 +1,78 @@ +#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); + + 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); + + StringArrayType get_keys(const Glib::ustring& group_name) const + SAFE_KEY_FILE_METHOD_NOINIT(get_keys(group_name), get_keys(group_name,error), StringArrayType); + +#undef SAFE_KEY_FILE_METHOD_CODE +#undef SAFE_KEY_FILE_METHOD +#undef SAFE_KEY_FILE_METHOD_NOINIT + +}; + +} + +#endif diff --git a/rtengine/settings.h b/rtengine/settings.h new file mode 100644 index 000000000..d725469e5 --- /dev/null +++ b/rtengine/settings.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 . + */ +#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 + + 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; + int amchroma; + int protectred; + double protectredh; + bool ciebadpixgauss; + int CRI_color; // N for display Lab value ; 0 disabled + // bool bw_complementary; + + /** 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..1faec01f2 --- /dev/null +++ b/rtengine/shmap.cc @@ -0,0 +1,383 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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" +#include "sleef.c" +#undef THREAD_PRIORITY_NORMAL +#ifdef __SSE2__ +#include "sleefsseavx.c" +#endif // __SSE2__ + +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); + } + + if (!hq) { +#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*radius;//1000; + LUTf rangefn(0x10000); + float ** dirpyrlo[2]; + + int intfactor = 1024;//16384; + + //set up range functions + for (int i=0; i<0x10000; i++) { + //rangefn[i] = (int)(((thresh)/((double)(i) + (thresh)))*intfactor); + rangefn[i] = static_cast(xexpf(-(min(10.0f,(static_cast(i)*i) / (thresh*thresh))))*intfactor); + //if (rangefn[i]<0 || rangefn[i]>intfactor) + //printf("i=%d rangefn=%d arg=%f \n",i,rangefn[i], float(i*i) / (thresh*thresh)); + } + + dirpyrlo[0] = allocArray (W, H); + dirpyrlo[1] = allocArray (W, H); + + int scale=1; + int level=0; + int indx=0; + dirpyr_shmap(map, dirpyrlo[indx], W, H, rangefn, 0, scale ); + scale *= 2; + level += 1; + indx = 1-indx; + while (skip*scale<16) { + dirpyr_shmap(dirpyrlo[1-indx], dirpyrlo[indx], W, H, rangefn, level, scale ); + scale *= 2; + level += 1; + indx = 1-indx; + } + + dirpyr_shmap(dirpyrlo[1-indx], map, W, H, rangefn, level, scale ); + + + freeArray(dirpyrlo[0], H); + freeArray(dirpyrlo[1], 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-64)*(W-64)); + avg = _avg; + +} + +void SHMap::forceStat (float max_, float min_, float avg_) { + + max_f = max_; + min_f = min_; + avg = avg_; +} + +#if defined( __SSE__ ) && defined( WIN32 ) +__attribute__((force_align_arg_pointer)) void SHMap::dirpyr_shmap(float ** data_fine, float ** data_coarse, int width, int height, LUTf & rangefn, int level, int scale) +#else +void SHMap::dirpyr_shmap(float ** data_fine, float ** data_coarse, int width, int height, LUTf & rangefn, int level, int scale) +#endif +{ + //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; +#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; + float norm=0; + + 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__ ) + for(; j < (width-scalewin)-3; j+=4) + { + valv= _mm_setzero_ps(); + normv= _mm_setzero_ps(); + + 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) { + dirwtv = ( rangefn[_mm_cvttps_epi32(vabsf(LVFU(data_fine[inbr][jnbr])-LVFU(data_fine[i][j])))] ); + valv += dirwtv*LVFU(data_fine[inbr][jnbr]); + normv += dirwtv; + } + } + _mm_storeu_ps( &data_coarse[i][j], valv/normv); + } + for(; j < width-scalewin; j++) + { + float val=0; + float norm=0; + + 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 + } + +#else + for(; j < width-scalewin; j++) + { + float val=0; + float norm=0; + + 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; + float norm=0; + + 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: + int W, H; + float** map; + float max_f, min_f, avg; + bool multiThread; + + 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_); + 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..fe6faf484 --- /dev/null +++ b/rtengine/simpleprocess.cc @@ -0,0 +1,733 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 "processingjob.h" +#include +#include "../rtgui/options.h" +#include +#include "rawimagesource.h" +#include "../rtgui/ppversion.h" +#include "../rtgui/multilangmgr.h" +//#include "mytime.h" + +#undef THREAD_PRIORITY_NORMAL +#ifdef _OPENMP +#include +#endif + +namespace rtengine { +extern const Settings* settings; + +IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* pl, bool tunnelMetaData) { + + 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 = 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; + if (params.coarse.hflip) tr |= TR_HFLIP; + if (params.coarse.vflip) tr |= TR_VFLIP; + + 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); + } + Imagefloat* baseImg = new Imagefloat (fw, fh); + imgsrc->getImage (currWB, tr, baseImg, pp, params.toneCurve, params.icm, params.raw); + if (pl) pl->setProgress (0.45); + + + // perform luma/chroma denoise +// CieImage *cieView; + + if (params.dirpyrDenoise.enabled) { + ipf.RGB_denoise(baseImg, baseImg, imgsrc->isRAW(), params.dirpyrDenoise, params.defringe, imgsrc->getDirPyrDenoiseExpComp()); + } + imgsrc->convertColorSpace(baseImg, params.icm, currWB, params.raw); + + // perform first analysis + LUTu hist16 (65536); + LUTu hist16C (65536); + + ipf.firstAnalysis (baseImg, ¶ms, hist16, imgsrc->getGamma()); + + // 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 +//!!!// 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 + //imgsrc->flushRawData(); + //imgsrc->flushRGB(); + + LUTf curve1 (65536,0); + LUTf curve2 (65536,0); + LUTf curve (65536,0); + LUTf satcurve (65536,0); + LUTf lhskcurve (65536,0); + LUTf lumacurve(65536,0); + LUTf clcurve (65536,0); + + LUTf rCurve (65536,0); + LUTf gCurve (65536,0); + LUTf bCurve (65536,0); + LUTu dummy; + + ToneCurve customToneCurve1, customToneCurve2; + ColorAppearance customColCurve1, customColCurve2,customColCurve3 ; + ToneCurve customToneCurvebw1; + ToneCurve customToneCurvebw2; + + ipf.g = imgsrc->getGamma(); + ipf.iGamma = true; + CurveFactory::complexCurve (expcomp, 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); + + 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; + autor = -9000.f; // This will ask to compute the "auto" values for the B&W tool (have to be inferior to -5000) + ipf.rgbProc (baseImg, labView, curve1, curve2, curve, shmap, params.toneCurve.saturation, rCurve, gCurve, bCurve, customToneCurve1, customToneCurve2,customToneCurvebw1, customToneCurvebw2, rrm, ggm, bbm, autor, autog, autob, expcomp, hlcompr, hlcomprthresh); + if (settings->verbose) + printf("Output image / Auto B&W coefs: R=%.2f G=%.2f B=%.2f\n", autor, autog, autob); + + // 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 (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 (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);//TODO: this is the luminance tonecurve, not the RGB one + + //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); + float adap2,adap; + double ada, ada2; + if(params.colorappearance.enabled){ + 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=adap2=2000.f;ada=ada2=2000.;}//if no exif data or wrong + 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; + adap2 = adap= powf(2.f, E_V-3.f);//cd / m2 + ada=ada2=(double) adap; + } + LUTf CAMBrightCurveJ; + LUTf CAMBrightCurveQ; + float CAMMean; + if (params.sharpening.enabled) { + float d; + double dd; + + float** buffer = new float*[fh]; + for (int i=0; iciecamfloat) ipf.ciecam_02float (cieView, adap, begh, endh,1,2, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, (float**)buffer, true, d); + else ipf.ciecam_02 (cieView, ada, begh, endh,1,2, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, (float**)buffer, true, dd); + for (int i=0; iciecamfloat) ipf.ciecam_02float (cieView, adap, begh, endh,1,2, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, (float**)buffer, true, d); + else ipf.ciecam_02 (cieView, adap, begh, endh,1, 2, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, (float**)buffer, true, dd); + + for (int i=0; isetProgress (0.60); + + // 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; + } + + Image16* readyImg = NULL; + cmsHPROFILE jprof = NULL; + bool customGamma = false; + bool useLCMS; + + if(params.icm.gamma != "default" || params.icm.freegamma) { // if select gamma output between BT709, sRGB, linear, low, high, 2.2 , 1.8 + cmsMLU *DescriptionMLU, *CopyrightMLU, *DmndMLU, *DmddMLU;// for modification TAG + + cmsToneCurve* GammaTRC[3] = { NULL, NULL, NULL }; + cmsFloat64Number Parameters[7]; + double ga0,ga1,ga2,ga3,ga4,ga5,ga6; + // wchar_t string[80] ; + int ns;//numero of stri[] + if (params.icm.working=="ProPhoto") ns=0; + else if (params.icm.working=="Adobe RGB") ns=1; + else if (params.icm.working=="sRGB") ns=2; + else if (params.icm.working=="WideGamut") ns=3; + else if (params.icm.working=="Beta RGB") ns=4; + else if (params.icm.working=="BestRGB") ns=5; + else if (params.icm.working=="BruceRGB") ns=6; + + + readyImg = ipf.lab2rgb16b (labView, cx, cy, cw, ch, params.icm.output, params.icm.working, params.icm.gamma, params.icm.freegamma, params.icm.gampos, params.icm.slpos, ga0,ga1,ga2,ga3,ga4,ga5,ga6 ); + customGamma = true; + + //or selected Free gamma + useLCMS=false; + bool pro=false; + Glib::ustring chpro, outProfile; + bool present_space[9]={false,false,false,false,false,false,false,false,false}; + std::vector 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); + if (settings->verbose) printf("Output profile: \"%s\"\n", params.icm.output.c_str()); + } + + delete labView; + labView = NULL; + + if (pl) pl->setProgress (0.70); + + if (params.resize.enabled) { + + // get the resize parameters + int refw, refh; + double tmpScale; + if (params.crop.enabled && params.resize.appliesTo == "Cropped area") { + // the resize values applies to the crop dimensions + refw = cw; + refh = ch; + } + 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 + tmpScale = (double)params.resize.width/(double)refw; + break; + case (2): + // Height + tmpScale = (double)params.resize.height/(double)refh; + break; + case (3): + // FitBox + if ((double)refw/(double)refh > (double)params.resize.width/(double)params.resize.height) + tmpScale = (double)params.resize.width/(double)refw; + else + tmpScale = (double)params.resize.height/(double)refh; + break; + default: + // Scale + tmpScale = params.resize.scale; + break; + } + + // resize image + if (fabs(tmpScale-1.0)>1e-5) { + int imw, imh; + if (params.crop.enabled && params.resize.appliesTo == "Full image") { + imw = cw; + imh = ch; + } + else { + imw = refw; + imh = refh; + } + imw = (int)( (double)imw * tmpScale + 0.5 ); + imh = (int)( (double)imh * tmpScale + 0.5 ); + 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); + 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) + Glib::Thread::create(sigc::bind(sigc::ptr_fun(batchProcessingThread), job, bpl, tunnelMetaData), 0, true, true, Glib::THREAD_PRIORITY_LOW); + +} + +} 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 100644 index 000000000..1f9452768 --- /dev/null +++ b/rtengine/sleef.c @@ -0,0 +1,1238 @@ +#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 ? -2147483648.0 : 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 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); + x = x * u * u * 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; + 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 = 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 * s + s; + t = q * (float)(M_PI/2) + t; + + return 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_PI /2)) : 0); + if (xisinff(y) ) r = M_PIf/2 - (xisinff(x) ? (signf(x) * (float)(M_PI*1/4)) : 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 = s * s * u + s + 1.0f; + u = ldexpkf(u, q); + +// if (xisminff(d)) u = 0; + return u; +} +__inline float xmul2f(float d) { + if (*(int*)&d & 0x7FFFFFFF) { // if f==0 do nothing + *(int*)&d += 1 << 23; // add 1 to the exponent + } + return d; +} + +__inline float xdiv2f(float d) { + if (*(int*)&d & 0x7FFFFFFF) { // if f==0 do nothing + *(int*)&d -= 1 << 23; // sub 1 from the exponent + } + return d; +} + +__inline float xdivf( float d, int n){ + if (*(int*)&d & 0x7FFFFFFF) { // if f==0 do nothing + *(int*)&d -= n << 23; // add n to the exponent + } + return d; +} + + + +#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..64a89d1d6 --- /dev/null +++ b/rtengine/sleefsseavx.c @@ -0,0 +1,1308 @@ +#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; + +static INLINE vfloat vmlaf(vfloat x, vfloat y, vfloat z) { return vaddf(vmulf(x, y), z); } +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)); } + +static INLINE vfloat vself(vmask mask, vfloat x, vfloat y) { + return (vfloat)vorm(vandm(mask, (vmask)x), vandnotm(mask, (vmask)y)); +} + +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 = vaddf(d, vmulf(vcast_vf_vi2(q), vcast_vf_f(-L2Uf))); + s = vaddf(s, vmulf(vcast_vf_vi2(q), vcast_vf_f(-L2Lf))); + + 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), vaddf(s, vmulf(vmulf(s, s), u))); + + 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 ); +} + +#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..607ffc99a --- /dev/null +++ b/rtengine/stdimagesource.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 "stdimagesource.h" +#include "mytime.h" +#include "iccstore.h" +#include "imageio.h" +#include "curves.h" +#include "color.h" + +#undef THREAD_PRIORITY_NORMAL + +namespace rtengine { + +extern cmsToneCurve* Color::linearGammaTRC; +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, RAWParams raw) { + colorSpaceConversion (image, cmp, embProfile, img->getSampleFormat()); +} + +void StdImageSource::colorSpaceConversion (Imagefloat* im, ColorManagementParams cmp, cmsHPROFILE embedded, IIOSampleFormat sampleFormat) { + + bool skipTransform = false; + cmsHPROFILE in; + 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 && cmp.input!="(none)") { + lcmsMutex->lock (); + cmsHTRANSFORM hTransform = cmsCreateTransform (in, TYPE_RGB_FLT, out, TYPE_RGB_FLT, settings->colorimetricIntent, + cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); + lcmsMutex->unlock (); + + // 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); + } +} + +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..4c2aeafd9 --- /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);// 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..54db707d5 --- /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) + +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..a62cf9c45 --- /dev/null +++ b/rtexif/canonattribs.cc @@ -0,0 +1,1526 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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; + } + + if (0 == nFound) { + std::ostringstream s; + s << "Unknown "; + if (focalLengthMin > 0.) + s << focalLengthMin; + if (focalLengthMax > 0. && focalLengthMax != focalLengthMin) + s << "-" << focalLengthMax; + if (focalLengthMin > 0.) + s << "mm"; + + s << " (" << lensID << ")"; + return s.str(); + } + double deltaMin = 1000.; + + std::string bestMatch("Unknown"); + 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[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[0x80000287] = "EOS 60D"; + } +}; +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..c3fe42e69 --- /dev/null +++ b/rtexif/nikonattribs.cc @@ -0,0 +1,934 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 Macro 105mm f/2.8 EX DG"; + 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["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..1d23998ee --- /dev/null +++ b/rtexif/pentaxattribs.cc @@ -0,0 +1,1434 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 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 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] = "DaylightFluorescent"; + choices[7] = "DaywhiteFluorescent"; + choices[8] = "WhiteFluorescent"; + choices[9] = "Flash"; + choices[10] = "Cloudy"; + 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 (Hi)"; + choices[3] = "Burst"; + choices[255] = "Video"; + choices1[0] = "No Timer"; + choices1[1] = "Self-timer (12 s)"; + choices1[2] = "Self-timer (2 s)"; + choices1[255] = "n/a"; + choices2[0] = "Shutter Button"; + choices2[1] = "Remote Control (3 s delay)"; + choices2[2] = "Remote Control"; + choices3[0] = "Single Exposure"; + choices3[1] = "Multiple Exposure"; + 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(); + } + } + return guess( lensID, focalLength, maxApertureAtFocal, liArray); + } +}; +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 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 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 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 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", &stdInterpreter}, + {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, 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", &paOnOffInterpreter}, + {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 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 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", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 1, AUTO, "AEAperture", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 2, AUTO, "AE_ISO", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 3, AUTO, "AEXv", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 4, AUTO, "AEBXv", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 5, AUTO, "AEMinExposureTime", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 6, AUTO, "AEProgramMode", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 9, AUTO, "AEMaxAperture", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 10, AUTO, "AEMaxAperture2", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 11, AUTO, "AEMinAperture", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 12, AUTO, "AEMeteringMode", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 14, AUTO, "FlashExposureCompSet", &stdInterpreter}, + {-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..1d3349ac5 --- /dev/null +++ b/rtexif/rtexif.cc @@ -0,0 +1,2263 @@ +/* + * 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(INTEL), 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; + 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); + for( const TagAttrib* tattr = ta; tattr->ignore != -1; tattr++){ + Tag* newTag = new Tag (this, tattr, (values + zeroOffset+ tattr->ID*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); + + for( const TagAttrib* tattr = ta; tattr->ignore != -1; tattr++){ + Tag* newTag = new Tag (this, tattr, (values + zeroOffset+ tattr->ID*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); + + 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); + char buffer[32],*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; + } + makerNoteKind = TABLESUBDIR; + 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)) { + switch( tag ){ + case 0x005c: + case 0x0205: + case 0x0206: + 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 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-5") || strstr(model, "K-r") ) + offsetFirst = 12; // LensInfo4 + else if( strstr(model, "K-01") || strstr(model, "K-30")) + offsetFirst = 15; // LensInfo5 + 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]; + fread (value, 1, valuesize, f); + } + // 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( "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 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 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 (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 + 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 (!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 = INTEL; + 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, INTEL); + +// 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; +} + +int getTypeSize( TagType type ){ + return ("11124811248484"[type<14?type:0]-'0'); +} + +/* 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..4dd816186 --- /dev/null +++ b/rtexif/rtexif.h @@ -0,0 +1,463 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 "../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, 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}; +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; } + const TagAttrib* getAttrib () const { return attrib; } + inline ByteOrder getOrder () const { return parent ? parent->getOrder() : INTEL; } + 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 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 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 int getTypeSize( TagType type ); + +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 pentaxAEInfoAttribs[]; +extern const TagAttrib pentaxCameraSettingsAttribs[]; +extern const TagAttrib pentaxFlashInfoAttribs[]; +extern const TagAttrib pentaxSRInfoAttribs[]; +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..04ebb05cf --- /dev/null +++ b/rtexif/sonyminoltaattribs.cc @@ -0,0 +1,2007 @@ +/* + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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(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 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(); + return guess( lensID, focalLength, maxApertureAtFocal, liArray); + } +}; +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(); + return guess( lensID, focalLength, maxApertureAtFocal, liArray); + } +}; +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..ab3a20b22 --- /dev/null +++ b/rtexif/stdattribs.cc @@ -0,0 +1,715 @@ +/* + * 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); + 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, 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..862ccab98 --- /dev/null +++ b/rtgui/CMakeLists.txt @@ -0,0 +1,70 @@ + +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 + 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 + 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 + 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 rawprocess.cc preprocess.cc + darkframe.cc flatfield.cc rawcacorrection.cc rawexposure.cc + dirpyrequalizer.cc hsvequalizer.cc defringe.cc + popupcommon.cc popupbutton.cc popuptogglebutton.cc sharpenedge.cc sharpenmicro.cc colorappearance.cc) + +include_directories (BEFORE "${CMAKE_CURRENT_BINARY_DIR}") + +if (APPLE) + # 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 gtkmacintegration) + set (EXTRA_INCDIR ${EXTRA_INCDIR} /opt/local/include/gtkmacintegration) +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}) + +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..7cb649bf9 --- /dev/null +++ b/rtgui/addsetids.h @@ -0,0 +1,83 @@ +#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 + +// When adding items, make sure to update ADDSET_PARAM_NUM +#define ADDSET_PARAM_NUM 71 // THIS IS USED AS A DELIMITER!! + +#endif diff --git a/rtgui/adjuster.cc b/rtgui/adjuster.cc new file mode 100644 index 000000000..0b24ba645 --- /dev/null +++ b/rtgui/adjuster.cc @@ -0,0 +1,493 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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; + + 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 (2); + + 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")); + + 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_end (*reset, Gtk::PACK_SHRINK, 0); + hbox->pack_end (*spin, Gtk::PACK_SHRINK, 0); + if (imgIcon2) hbox->pack_start (*imgIcon2, Gtk::PACK_SHRINK, 0); + hbox->pack_start (*slider, true, true); + } + 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) ); + } +} + +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..9bd3fa813 --- /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..3e1ed081a --- /dev/null +++ b/rtgui/batchqueue.cc @@ -0,0 +1,918 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 "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 () : processing(NULL), sequence(0), listener(NULL) { + + int p = 0; + pmenu = new Gtk::Menu (); + 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); + 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); + + 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); +} + +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_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::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")); + + 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 + delete processing; processing = NULL; + bool queueEmptied=false; + { + // TODO: Check for Linux + #if PROTECT_VECTORS + MYWRITERLOCK(l, entryRW); + #endif + + 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 + { + // ButtonSet have Cairo::Surface which might be rendered while we're trying to delete them + GThreadLock lock; + next->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..9a3571b54 --- /dev/null +++ b/rtgui/batchqueue.h @@ -0,0 +1,105 @@ +/* + * 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 + int sequence; // holds the current sequence index + + Glib::ustring nameTemplate; + + Gtk::ImageMenuItem* cancel; + Gtk::ImageMenuItem* head; + Gtk::ImageMenuItem* tail; + Gtk::MenuItem* selall; + 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 (); + ~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 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); + 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..77bd3f690 --- /dev/null +++ b/rtgui/batchqueuepanel.cc @@ -0,0 +1,332 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 () { + + batchQueue = Gtk::manage( new BatchQueue() ); + + // 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_text (M("FILEBROWSER_STARTPROCESSINGHINT")); + stop->set_tooltip_text (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); + } +} + + +void BatchQueuePanel::updateTab (int qsize) +{ + Gtk::Notebook *nb =(Gtk::Notebook *)(this->get_parent()); + + if (options.mainNBVertical) { + 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) { + return batchQueue->keyPressed (event); +} diff --git a/rtgui/batchqueuepanel.h b/rtgui/batchqueuepanel.h new file mode 100644 index 000000000..1adb3c3be --- /dev/null +++ b/rtgui/batchqueuepanel.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 _BATCHQUEUEPANEL_ +#define _BATCHQUEUEPANEL_ + +#include +#include "batchqueue.h" +#include "saveformatpanel.h" +#include "guiutils.h" + +class RTWindow; +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 (); + + 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); + + bool handleShortcutKey (GdkEventKey* event); +}; +#endif + diff --git a/rtgui/batchtoolpanelcoord.cc b/rtgui/batchtoolpanelcoord.cc new file mode 100644 index 000000000..b1f1db385 --- /dev/null +++ b/rtgui/batchtoolpanelcoord.cc @@ -0,0 +1,470 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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(), 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); + + shadowshighlights->setAdjusterBehavior (false, false, false); + dirpyrequalizer->setAdjusterBehavior (false, false); + dirpyrdenoise->setAdjusterBehavior (false, false,false,false,false,false); + preprocess->setAdjusterBehavior (false, false); + rawcacorrection->setAdjusterBehavior (false); + rawexposure->setAdjusterBehavior (false, false, 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]); + + 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]); + 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]); + preprocess->setAdjusterBehavior (options.baBehav[ADDSET_PREPROCESS_LINEDENOISE], options.baBehav[ADDSET_PREPROCESS_GREENEQUIL]); + rawcacorrection->setAdjusterBehavior (options.baBehav[ADDSET_RAWCACORR]); + rawexposure->setAdjusterBehavior (options.baBehav[ADDSET_RAWEXPOS_LINEAR], options.baBehav[ADDSET_RAWEXPOS_PRESER], 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_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<5; i++) pparams.dirpyrequalizer.mult[i] = 0; + if (options.baBehav[ADDSET_DIRPYREQ_THRESHOLD]) pparams.dirpyrequalizer.threshold = 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_PREPROCESS_GREENEQUIL]) pparams.raw.greenthresh = 0; + if (options.baBehav[ADDSET_PREPROCESS_LINEDENOISE]) pparams.raw.linenoise = 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.blackzero = pparams.raw.blackone = pparams.raw.blacktwo = pparams.raw.blackthree = 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); + + // TODO: We may update the crop on coarse rotate events here, like in ToolPanelCoordinator::panelChanged + + 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/blackwhite.cc b/rtgui/blackwhite.cc new file mode 100644 index 000000000..f9bcab58a --- /dev/null +++ b/rtgui/blackwhite.cc @@ -0,0 +1,1278 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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" + +using namespace rtengine; +using namespace rtengine::procparams; + + +BlackWhite::BlackWhite (): Gtk::VBox(), FoldableToolPanel(this) { + CurveListener::setMulti(true); + set_border_width(4); + set_spacing(4); + + nextredbw = 0.3333; + nextgreenbw = 0.3333; + nextbluebw = 0.3333; + + //----------- Enables checkbox ------------------------------ + + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); + enabled->set_active (false); + + pack_start(*enabled, Gtk::PACK_SHRINK, 0); + enabled->show (); + enaconn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &BlackWhite::enabled_toggled) ); + + pack_start (*Gtk::manage (new Gtk::HSeparator())); + + //----------- 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->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); + + 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->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->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(); +} +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); + enaconn.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; + enabled->set_active (pp->blackwhite.enabled); + lastEnabled = 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; + + if (pedited) { + luminanceCurve->setUnChanged (!pedited->blackwhite.luminanceCurve); + beforeCurve->setUnChanged (!pedited->blackwhite.beforeCurve); + afterCurve->setUnChanged (!pedited->blackwhite.afterCurve); + autoch->set_inconsistent (!pedited->blackwhite.autoc); + enabled->set_inconsistent (!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); + enaconn.block (false); + enaccconn.block (false); + + updateRGBLabel(); + + enableListener (); +} + +void BlackWhite::write (ProcParams* pp, ParamsEdited* pedited) { + pp->blackwhite.enabled = enabled->get_active (); + 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 = !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.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"; + + pp->blackwhite.setting = getSettingString(); + pp->blackwhite.filter = getFilterString(); +} + +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, int callerId, ColorCaller* caller) { + + float r, g, b; + + 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||enabled->get_active())) { + 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||enabled->get_active())) { + 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||enabled->get_active())) { + listener->panelChanged (EvBWmethod, method->get_active_text ()); + } +} + +void BlackWhite::enabled_toggled () { + + if (multiImage) { + if (enabled->get_inconsistent()) { + enabled->set_inconsistent (false); + enaconn.block (true); + enabled->set_active (false); + enaconn.block (false); + } + else if (lastEnabled) + enabled->set_inconsistent (true); + + lastEnabled = enabled->get_active (); + } + + if (listener) { + if (enabled->get_inconsistent()) + listener->panelChanged (EvBWChmixEnabled, M("GENERAL_UNCHANGED")); + else if (enabled->get_active ()) { + 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||enabled->get_active())) { + 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; + Glib::ustring sSetting = getSettingString(); + Color::computeBWMixerConstants(sSetting, getFilterString(), r, g, b, + mixerOrange->getValue(), mixerYellow->getValue(), mixerCyan->getValue(), mixerPurple->getValue(), mixerMagenta->getValue(), + autoch->get_active(), enabledcc->get_active(), kcorrec, mixR, mixG, mixB); + 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); + beforeCurveMode->append_text (M("GENERAL_UNCHANGED")); + afterCurveCEG->setBatchMode (batchMode); +// afterCurveMode->append_text (M("GENERAL_UNCHANGED")); + + showLuminance(); + showFilter(); + showEnabledCC(); + showGamma(); + showMixer(7); +} + +void BlackWhite::autoOpenCurve () { + luminanceCurve->openIfNonlinear(); + beforeCurve->openIfNonlinear(); + afterCurve->openIfNonlinear(); +} + +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(); + 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(); + 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::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..804a5f569 --- /dev/null +++ b/rtgui/blackwhite.h @@ -0,0 +1,133 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 Gtk::VBox, 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; + + 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::CheckButton* enabled; + bool lastEnabled; + sigc::connection enaconn; + + 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 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 enabled_toggled (); + void methodChanged (); + void filterChanged (); + void settingChanged (); + virtual void colorForValue (double valX, double valY, 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_ (); + + Glib::ustring getSettingString (); + Glib::ustring getFilterString (); +}; + +#endif diff --git a/rtgui/bqentryupdater.cc b/rtgui/bqentryupdater.cc new file mode 100644 index 000000000..17e509315 --- /dev/null +++ b/rtgui/bqentryupdater.cc @@ -0,0 +1,170 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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; + + #undef THREAD_PRIORITY_LOW + thread = Glib::Thread::create(sigc::mem_fun(*this, &BatchQueueEntryUpdater::processThread), (unsigned long int)0, true, true, Glib::THREAD_PRIORITY_LOW); + } +} + +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..e4fe33dfb --- /dev/null +++ b/rtgui/cacheimagedata.cc @@ -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 . + */ +#include "cacheimagedata.h" +#include +#include +#include "../rtengine/safekeyfile.h" +#include "../rtengine/safegtk.h" +#include "version.h" + +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) { + + 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"); + if (keyFile.has_key ("DateTime", "MSec")) msec = keyFile.get_integer ("DateTime", "MSec"); + } + + 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_integer ("DateTime", "MSec", msec); + } + + 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..5d3f11432 --- /dev/null +++ b/rtgui/cacheimagedata.h @@ -0,0 +1,83 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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; + char msec; + // 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 rhe 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..894b574eb --- /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::FileError& fe) { + } +} + +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..0ac29e333 --- /dev/null +++ b/rtgui/cacorrection.cc @@ -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 . + */ +#include "cacorrection.h" +#include +#include "rtimage.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +CACorrection::CACorrection () : Gtk::VBox(), FoldableToolPanel(this) { + + set_border_width(4); + + 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..a93e582de --- /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 Gtk::VBox, 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..7edc7d68f --- /dev/null +++ b/rtgui/chmixer.cc @@ -0,0 +1,187 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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; + +extern Glib::ustring argv0; + +ChMixer::ChMixer (): Gtk::VBox(), FoldableToolPanel(this) { + + set_border_width(4); + + 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..2490344f6 --- /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 Gtk::VBox, 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..0b3054bad --- /dev/null +++ b/rtgui/clipboard.h @@ -0,0 +1,67 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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; } + 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..a09bd8f3b --- /dev/null +++ b/rtgui/coarsepanel.cc @@ -0,0 +1,146 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 () { + + degree = (degree + 270) % 360; + degreechanged = true; + if (listener) + listener->panelChanged (EvCTRotate, Glib::ustring::format (degree)); +} + +void CoarsePanel::rotateRight () { + + degree = (degree + 90) % 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..1bb797c38 --- /dev/null +++ b/rtgui/colorappearance.cc @@ -0,0 +1,1219 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 +#include "guiutils.h" +#include "../rtengine/color.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +ColorAppearance::ColorAppearance () : Gtk::VBox(), FoldableToolPanel(this) { + CurveListener::setMulti(true); + std::vector milestones; + milestones.push_back( GradientMilestone(0., 0., 0., 0.) ); + milestones.push_back( GradientMilestone(1., 1., 1., 1.) ); + + set_border_width(4); + + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); + enabled->set_active (false); + pack_start (*enabled); + + + // ------------------------ 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) ); + enaConn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &ColorAppearance::enabledChanged) ); + 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); + + enabled->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); + } + + + } + + enaConn.block (true); + enabled->set_active (pp->colorappearance.enabled); + enaConn.block (false); + + 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; + + lastEnabled = pp->colorappearance.enabled; + 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 = enabled->get_active(); + 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 = !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, int callerId, ColorCaller *caller) { + + float R, G, B; + 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||enabled->get_active()) ) { + 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||enabled->get_active()) ) { + + 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 (multiImage) { + if (enabled->get_inconsistent()) { + enabled->set_inconsistent (false); + enaConn.block (true); + enabled->set_active (false); + enaConn.block (false); + } + else if (lastEnabled) + enabled->set_inconsistent (true); + + lastEnabled = enabled->get_active (); + } + + if (listener) { + if (enabled->get_inconsistent()) + listener->panelChanged (EvCATEnabled, M("GENERAL_UNCHANGED")); + else if (enabled->get_active ()) { + 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||enabled->get_active()) ) { + listener->panelChanged (EvCATMethodsur, surround->get_active_text ()); + } +} + +void ColorAppearance::wbmodelChanged () { + + if (listener && (multiImage||enabled->get_active()) ) { + 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||enabled->get_active()) ) { + 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..cbf55bcc9 --- /dev/null +++ b/rtgui/colorappearance.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 _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 Gtk::VBox, 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; + + Gtk::CheckButton* enabled; + 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 lastEnabled; + bool lastAutoDegree; + bool lastAutoAdapscen; + sigc::connection enaConn; + 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, int callerId, ColorCaller *caller); +}; + +#endif diff --git a/rtgui/coloredbar.cc b/rtgui/coloredbar.cc new file mode 100644 index 000000000..6f005c437 --- /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::Surface + */ +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, 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, 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, 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, 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..657896abd --- /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..a1f8e1085 --- /dev/null +++ b/rtgui/colorprovider.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 _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: + 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, 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/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 Glib::ustring argv0; +extern Options options; + +class RefreshSpinHelper { + + public: + Crop* crop; + bool notify; + RefreshSpinHelper (Crop* _crop, bool _notify) + : crop(_crop), notify(_notify) {} +}; + +Crop::Crop (): Gtk::VBox(), FoldableToolPanel(this) { + + set_border_width(4); + + clistener = NULL; + + maxw = 3000; + maxh = 2000; + + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); + enabled->set_active (false); + pack_start(*enabled); + + pack_start(*Gtk::manage (new Gtk::HSeparator()), Gtk::PACK_EXPAND_WIDGET, 4); + + 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->set_active (0); + + guide->append_text (M("TP_CROP_GTNONE")); + guide->append_text (M("TP_CROP_GTRULETHIRDS")); + guide->append_text (M("TP_CROP_GTDIAGONALS")); + guide->append_text (M("TP_CROP_GTHARMMEANS1")); + guide->append_text (M("TP_CROP_GTHARMMEANS2")); + guide->append_text (M("TP_CROP_GTHARMMEANS3")); + guide->append_text (M("TP_CROP_GTHARMMEANS4")); + guide->append_text (M("TP_CROP_GTGRID")); + guide->append_text (M("TP_CROP_GTEPASSPORT")); + guide->append_text (M("TP_CROP_GTFRAME")); + 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); + econn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &Crop::enabledChanged) ); + 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); + econn.block (true); + oconn.block (true); + gconn.block (true); + + enabled->set_active (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); + + if (pp->crop.orientation == "Landscape") + orientation->set_active (0); + else if (pp->crop.orientation == "Portrait") + orientation->set_active (1); + + if (pp->crop.guide == "None") + guide->set_active (0); + else if (pp->crop.guide == "Rule of thirds") + guide->set_active (1); + else if (pp->crop.guide == "Rule of diagonals") + guide->set_active (2); + else if (pp->crop.guide == "Harmonic means 1") + guide->set_active (3); + else if (pp->crop.guide == "Harmonic means 2") + guide->set_active (4); + else if (pp->crop.guide == "Harmonic means 3") + guide->set_active (5); + else if (pp->crop.guide == "Harmonic means 4") + guide->set_active (6); + else if (pp->crop.guide == "Grid") + guide->set_active (7); + else if (pp->crop.guide == "ePassport") + guide->set_active (8); + else if (pp->crop.guide == "Frame") + guide->set_active (9); + + 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 (8); + if (!pedited->crop.orientation) + orientation->set_active (2); + if (!pedited->crop.guide) + guide->set_active (7); + enabled->set_inconsistent (!pedited->crop.enabled); + fixr->set_inconsistent (!pedited->crop.fixratio); + } + + lastEnabled = pp->crop.enabled; + lastFixRatio = pp->crop.fixratio; + + xconn.block (false); + yconn.block (false); + wconn.block (false); + hconn.block (false); + rconn.block (false); + fconn.block (false); + econn.block (false); + oconn.block (false); + gconn.block (false); + + enableListener (); +} + +void Crop::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->crop.enabled = enabled->get_active (); + 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 (); + + if (orientation->get_active_row_number()==0) + pp->crop.orientation = "Landscape"; + else if (orientation->get_active_row_number()==1) + pp->crop.orientation = "Portrait"; + + if (guide->get_active_row_number()==0) + pp->crop.guide = "None"; + else if (guide->get_active_row_number()==1) + pp->crop.guide = "Rule of thirds"; + else if (guide->get_active_row_number()==2) + pp->crop.guide = "Rule of diagonals"; + else if (guide->get_active_row_number()==3) + pp->crop.guide = "Harmonic means 1"; + else if (guide->get_active_row_number()==4) + pp->crop.guide = "Harmonic means 2"; + else if (guide->get_active_row_number()==5) + pp->crop.guide = "Harmonic means 3"; + else if (guide->get_active_row_number()==6) + pp->crop.guide = "Harmonic means 4"; + else if (guide->get_active_row_number()==7) + pp->crop.guide = "Grid"; + else if (guide->get_active_row_number()==8) + pp->crop.guide = "ePassport"; + else if (guide->get_active_row_number()==9) + pp->crop.guide = "Frame"; + + if (pedited) { + pedited->crop.enabled = !enabled->get_inconsistent(); + pedited->crop.ratio = ratio->get_active_row_number() != 9; + pedited->crop.orientation = orientation->get_active_row_number() != 2; + pedited->crop.guide = guide->get_active_row_number() != 9; + 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 { + bool unsetRatio = false; + if ((xmin + pp->crop.w) > ow) { + // crop overflow in the width dimension ; we trim it + pp->crop.w = ow-xmin; + unsetRatio = true; + } + if ((ymin + pp->crop.h) > oh) { + // crop overflow in the height dimension ; we trim it + pp->crop.h = oh-ymin; + unsetRatio = true; + } + if (unsetRatio) { + // the ratio is certainly not respected anymore, so we set it off + pp->crop.fixratio = false; + } + } +} + +void Crop::selectPressed () { + + if (clistener) + clistener->cropSelectRequested (); +} + +void Crop::notifyListener () { + + if (listener && enabled->get_active ()) + 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 (batchMode) { + if (enabled->get_inconsistent()) { + enabled->set_inconsistent (false); + econn.block (true); + enabled->set_active (false); + econn.block (false); + } + else if (lastEnabled) + enabled->set_inconsistent (true); + + lastEnabled = enabled->get_active (); + } + + if (listener) { + if (enabled->get_active ()) + 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)); + 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) { + + int tmp; + switch ((360+deg-lastRotationDeg)%360) { + 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 (enabled->get_active()==false) { + 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); + if (H > maxh) { + H = maxh; + 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); + if (H > maxh) { + H = maxh; + 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); + if (W > maxw) { + W = maxw; + 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); + if (W > maxw) { + W = maxw; + 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; + + econn.block (true); + enabled->set_active (1); + econn.block (false); + g_idle_add (refreshSpinsUI, new RefreshSpinHelper (this, false)); +// Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins)); +} + +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 (orientation->get_active_row_number()==0) + return r; + else + return 1.0 / r; +} + +void Crop::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + + ratio->append_text ("(Unchanged)"); + orientation->append_text ("(Unchanged)"); + guide->append_text ("(Unchanged)"); + removeIfThere (this, ppibox); +} diff --git a/rtgui/crop.h b/rtgui/crop.h new file mode 100644 index 000000000..6e7ef5310 --- /dev/null +++ b/rtgui/crop.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 _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 Gtk::VBox, public CropGUIListener, public FoldableToolPanel, public rtengine::SizeListener { + + protected: + Gtk::CheckButton* enabled; + 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, econn, fconn, rconn, oconn, gconn; + bool wDirty, hDirty, xDirty, yDirty, lastEnabled, 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 (); + double getRatio (); + + void setCropPanelListener (CropPanelListener* cl) { clistener = cl; } + + void resizeScaleChanged (double rsc); + void hFlipCrop (); + void vFlipCrop (); + void rotateCrop (int deg); +}; + +#endif diff --git a/rtgui/cropguilistener.h b/rtgui/cropguilistener.h new file mode 100644 index 000000000..dc0a803bc --- /dev/null +++ b/rtgui/cropguilistener.h @@ -0,0 +1,40 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 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 double getRatio () =0; +}; + +#endif diff --git a/rtgui/crophandler.cc b/rtgui/crophandler.cc new file mode 100644 index 000000000..4efcaa466 --- /dev/null +++ b/rtgui/crophandler.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. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 "../rtengine/refreshmap.h" + +using namespace rtengine; + +CropHandler::CropHandler () + : zoom(10), 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) { + + 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 (); + crop = NULL; + } + cimg.lock (); + if (chi->pending) + chi->destroyed = true; + else + delete chi; + cimg.unlock (); +} + +void CropHandler::newImage (StagedImageProcessor* ipc_) { + + ipc = ipc_; + cx = 0; + cy = 0; + + if (!ipc) + return; + + crop = ipc->createCrop (); + 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::getFitZoom () { + + if (ipc) { + double z1 = (double) wh / ipc->getFullHeight (); + 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..cd0c7406d --- /dev/null +++ b/rtgui/crophandler.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 __CROPHANDLER__ +#define __CROPHANDLER__ + +#include "../rtengine/rtengine.h" +#include "threadutils.h" +#include + +class CropHandlerListener { + + public: + 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 newImage (rtengine::StagedImageProcessor* ipc_); + void setZoom (int z, int centerx=-1, int centery=-1); + double getFitZoom (); + 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 (); + + // 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..e4fe21db8 --- /dev/null +++ b/rtgui/cropwindow.cc @@ -0,0 +1,1501 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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" + +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_) + : 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) { + + 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; + + resizeSurface = safe_create_from_png ("resize.png"); + bZoomIn = new LWButton (safe_create_from_png ("gtk-zoom-in.png"), 0, NULL, LWButton::Left, LWButton::Center, "Zoom In"); + bZoomOut = new LWButton (safe_create_from_png ("gtk-zoom-out.png"), 1, NULL, LWButton::Left, LWButton::Center, "Zoom Out"); + bZoom100 = new LWButton (safe_create_from_png ("gtk-zoom-100.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.png"), 4, NULL, LWButton::Right, LWButton::Center, "Close"); + + buttonSet.add (bZoomIn); + buttonSet.add (bZoomOut); + 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.newImage (ipc_); + + cropHandler.setEnabled (true); + cropHandler.setCropHandlerListener (this); + + + state = SNormal; +} + +CropWindow::~CropWindow () { + +} + +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) { + + cropHandler.setPosition (x, y); + 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 && ygrabFocus (this); + if (button==1 && type==GDK_2BUTTON_PRESS && onArea (CropImage, x, y) && (state==SNormal || state==SCropImgMove)) { + if (fitZoomEnabled) { + if (fitZoom) { + state = SNormal; + zoomVersion = exposeVersion; + translateCoord (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 (onArea (CropObserved, x, y)) { + state = SObservedMove; + press_x = x; + press_y = y; + } + 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) { + state = SCropImgMove; + action_x = 0; + action_y = 0; + 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) { + translateCoord (x, y, action_x, action_y); + iarea->spotWBSelected (action_x, action_y); + } + else if (iarea->getToolMode () == TMCropSelect && cropgl) { + state = SCropSelecting; + translateCoord (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) { + 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) { + + if (state==SCropWinResize) { + setSize (press_x + x - action_x, press_y + y - action_y); + state = SNormal; + for (std::list::iterator i=listeners.begin(); i!=listeners.end(); i++) + (*i)->cropWindowSizeChanged (this); + } + 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); + } + else if (state==SRotateSelecting) { + iarea->straightenReady (rot_deg); + iarea->setToolHand (); + } + else if (state==SObservedMove) { + observedCropWin->remoteMoveReady (); + state = SNormal; + } + 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 (); + } + + if (decorated) + buttonSet.releaseNotify (x, y); + if (deleted) + return; + + state = SNormal; + iarea->grabFocus (NULL); + iarea->redraw (); + updateCursor (x, y); +} + +void CropWindow::pointerMoved (int x, int y) { + + 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) { + translateCoord (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 (); + } + 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; + translateCoord (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); + } + 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]); + if (pmhlistener) { + pmhlistener->pointerMoved (true, 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: + translateCoord (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: + translateCoord (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: + translateCoord (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: + translateCoord (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 && xgetToolMode (); + + 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)) { + 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); + + //MyTime t1, t2, t3, t4; + + //t1.set (); + + 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++; +// PERFORMANCE BOTTLENECK STARTS HERE + //t3.set (); + bool showcs = iarea->indClippedPanel->showClippedShadows(); + bool showch = iarea->indClippedPanel->showClippedHighlights(); + bool showR = iarea->previewModePanel->showR(); // will show clipping if R channel is clipped + bool showG = iarea->previewModePanel->showG(); // will show clipping if G channel is clipped + bool showB = iarea->previewModePanel->showB(); // will show clipping if B channel is clipped + bool showL = iarea->previewModePanel->showL(); // will show clipping if L value is clipped + bool showFocusMask = iarea->previewModePanel->showFocusMask(); + bool showclippedAny = (!showR && !showG && !showB && !showL); // will show clipping if any of RGB chanels is clipped + + // 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(); + + int pixRowStride = tmp->get_rowstride (); + int pixWSRowStride = cropHandler.cropPixbuftrue->get_rowstride (); + + const float ShawdowFac = 64 / (options.shadowThreshold+1); + const float HighlightFac = 64 / (256-options.highlightThreshold); + + #ifdef _OPENMP + #pragma omp parallel for + #endif + for (int i=0; iget_height(); i++) { + guint8* curr = pix + i*pixRowStride; + guint8* currWS = pixWrkSpace + i*pixWSRowStride; + + int delta; bool changedHL; bool changedSH; + + for (int j=0; jget_width(); j++) { + + + if (showFocusMask){ // modulate preview to display focus mask + + //************* + // Copyright (c) 2011 Michael Ezra michael@michaelezra.com + // determine if pixel is in the sharp area of the image using + // standard deviation analysis on two different scales + int blur_radius, blur_radius2; + float curL; + guint8* currIndex; + float avg_L, avg_L2; + float sum_L, sum_L2; + float sumsq_L, sumsq_L2; //sum of deviations squared + float stdDev_L, stdDev_L2; + float focus_thresh, focus_thresh2; + int kernel_size, kernel_size2;// count of pixels in the blur kernel + float opacity = 0.9;//TODO: implement opacity + //TODO: evaluate effects of altering sampling frequency + + + //TODO: dynamically determine appropriate values based on image analysis + blur_radius=4;; + focus_thresh=80; + + blur_radius2 = blur_radius/4; // Band2 + focus_thresh2 = focus_thresh/2; // Band 2 threshold + + if (j>blur_radius && jget_width()-blur_radius + && i>blur_radius && iget_height()-blur_radius){ //stay within image area + // calculate average in +-blur_radius pixels area around the current pixel + // speed up: calculate sum of squares in the same loops + + sum_L = 0; sum_L2=0; + sumsq_L = 0; sumsq_L2 = 0; + for (int kh=-blur_radius; kh<=blur_radius;kh++){ + for (int k=-blur_radius; k<=blur_radius;k++){ + //1 pixel step is equivalent to 3-bytes step + currIndex = currWS+3*k + kh*pixWSRowStride; + curL = 0.299*(currIndex)[0]+0.587*(currIndex)[1]+0.114*(currIndex)[2]; + sum_L += curL; + sumsq_L += SQR(curL); + + // Band2 @ blur_radius2 + if (kh>=-blur_radius2 && kh<=blur_radius2 && k>=-blur_radius2 && k<=blur_radius2){ + sum_L2 += curL; + sumsq_L2 += SQR(curL); + } + } + } + //************* + // averages + kernel_size= SQR(2*blur_radius+1); // consider -1: Bessel's correction for the sample standard deviation (tried, did not make any visible difference) + kernel_size2= SQR(2*blur_radius2+1); + avg_L = sum_L/kernel_size; + avg_L2 = sum_L2/kernel_size2; + + + stdDev_L = sqrt(sumsq_L/kernel_size - SQR(avg_L)); + stdDev_L2 = sqrt(sumsq_L2/kernel_size2 - SQR(avg_L2)); + + //TODO: try to normalize by average L of the entire (preview) image + + //detection method 1: detect focus in features + //there is no strict condition between stdDev_L and stdDev_L2 themselves +/* if (stdDev_L2>focus_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_thresh/10 //options.highlightThreshold + ){ + curr[0]=0; + curr[1]=255; + curr[2]=0; + } + } + } + + else { // !showFocusMask + + // we must compare clippings in working space, since the cropPixbuf is in sRGB, with mon profile + + changedHL=false; + changedSH=false; + + // for efficiency, pre-calculate currWS_L as it may be needed in both + // if (showch) and if (showcs) branches + int currWS_L; + if (showL && (showch||showcs)) currWS_L = (int)(0.299*currWS[0]+0.587*currWS[1]+0.114*currWS[2]); + + if (showch) { + delta=0; changedHL=false; + + if (currWS[0]>=options.highlightThreshold && (showR || showclippedAny)) { delta += 255-currWS[0]; changedHL=true; } + if (currWS[1]>=options.highlightThreshold && (showG || showclippedAny)) { delta += 255-currWS[1]; changedHL=true; } + if (currWS[2]>=options.highlightThreshold && (showB || showclippedAny)) { delta += 255-currWS[2]; changedHL=true; } + if (currWS_L>= options.highlightThreshold && showL) { 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) { + delta=0; changedSH=false; + + if (currWS[0]<=options.shadowThreshold && (showR || showclippedAny)) { delta += currWS[0]; changedSH=true; } + if (currWS[1]<=options.shadowThreshold && (showG || showclippedAny)) { delta += currWS[1]; changedSH=true; } + if (currWS[2]<=options.shadowThreshold && (showB || showclippedAny)) { delta += currWS[2]; changedSH=true; } + if (currWS_L <=options.shadowThreshold && showL) { 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){ //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; + } + } + } // else (!showFocusMask) + + + + /* + 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); + //t4.set (); +// END OF BOTTLENECK + 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); + } + if (observedCropWin) + drawObservedFrame (cr); + } + 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); + } + if (observedCropWin) + drawObservedFrame (cr, rough->get_width(), rough->get_height()); + } + } + } + + // if cursor stays above resize area, draw the icon + if (decorated && (state==SCropWinResize || onResizeArea)) { + int rw = resizeSurface->get_width (); + int rh = resizeSurface->get_height (); + cr->set_source_rgb (0.5,0.5,0.5); + cr->rectangle (x+w-1.5-rw-1, y+h-1.5-rh-1, rw+1, rh+1); + cr->stroke_preserve (); + cr->fill (); + cr->set_source (resizeSurface, x+w-1.5-rw, y+h-1.5-rh); + cr->paint (); + cr->set_source_rgb (0,0,0); + cr->move_to (x+w-2.5-rw, y+h-1.5); + cr->line_to (x+w-2.5-rw, y+h-2.5-rh); + cr->line_to (x+w-1.5, y+h-2.5-rh); + cr->stroke (); + } + if (state==SRotateSelecting) + drawStraightenGuide (cr); + if (state==SNormal && iarea->getToolMode () == TMSpotWB) + drawSpotWBRectangle (cr); + + //t2.set (); +// printf ("etime --> %d, %d\n", t2.etime (t1), t4.etime (t3)); +} + +// calculate the center of the zommed in/out preview given a cursor position +void CropWindow::findCenter (int deltaZoom, int& x, int& y) { + int cursorX, cursorY; + translateCoord(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) { + translateCoord(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); +} + +void CropWindow::zoomFit () { + + 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); + fitZoom = true; +} + +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 + deleted = true; + iarea->cropWindowClosed (this); + } +} + +void CropWindow::redrawNeeded (LWButton* button) { + + iarea->redraw (); +} + +void CropWindow::changeZoom (int zoom, bool notify, int centerx, int centery) { + + if (zoom<0) + zoom = 0; + else if (zoom>MAXZOOMSTEPS) + zoom = MAXZOOMSTEPS; + + if (cropZoom == zoom) { + // 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::translateCoord (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::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,0,0); + cr->set_line_width (1.0); + cr->move_to (x+0.5, y+h-0.5); + cr->line_to (x+0.5, y+0.5); + cr->line_to (x+w-0.5, y+0.5); + cr->stroke (); + cr->set_source_rgb (1,1,1); + cr->move_to (x+w-0.5, y+0.5); + cr->line_to (x+w-0.5, y+h-0.5); + cr->line_to (x+0.5, y+h-0.5); + cr->stroke (); + cr->set_source_rgb (0.5,0.5,0.5); + cr->rectangle (x+1.5, y+1.5+titleHeight, w-3, h-titleHeight-3); + cr->stroke (); + cr->set_source_rgb (1,1,1); + cr->move_to (x+2.5, y+h-2.5); + cr->line_to (x+2.5, y+titleHeight+2.5); + cr->line_to (x+w-2.5, y+titleHeight+2.5); + cr->stroke (); + cr->set_source_rgb (0,0,0); + cr->move_to (x+w-2.5, y+titleHeight+2.5); + cr->line_to (x+w-2.5, y+h-2.5); + cr->line_to (x+2.5, y+h-2.5); + cr->stroke (); + cr->set_source_rgb (0.5,0.5,0.5); + cr->rectangle (x+1.5, y+1.5, w-3, titleHeight); + cr->stroke_preserve (); + cr->fill (); + + // draw label + cr->set_source_rgb (1,1,1); + cr->move_to (x+6+sideBorderWidth+bZoomIn->getIcon()->get_width()+bZoomOut->getIcon()->get_width()+bZoom100->getIcon()->get_width(), y+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.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 (); + } +} + +void CropWindow::drawSpotWBRectangle (Cairo::RefPtr cr) { + + int rectsize = iarea->getSpotWBRectSize (); + 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::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); + + cr->set_source_rgb (1.0, 1.0, 1.0); + cr->set_line_width (4); + cr->rectangle (x-2, y-2, w+4, h+4); + cr->stroke (); + cr->set_source_rgb (1.0, 0.0, 0.0); + cr->set_line_width (2); + cr->rectangle (x-2, y-2, 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++; +} diff --git a/rtgui/cropwindow.h b/rtgui/cropwindow.h new file mode 100755 index 000000000..efb7adfea --- /dev/null +++ b/rtgui/cropwindow.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 _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 void cropPositionChanged (CropWindow*) {} + virtual void cropWindowSizeChanged (CropWindow*) {} + virtual void cropZoomChanged (CropWindow*) {} + virtual void initialImageArrived (CropWindow*) {} +}; + +class ImageArea; +class CropWindow : public LWButtonListener, public CropHandlerListener { + + // 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 + Cairo::RefPtr resizeSurface; + LWButton *bZoomIn, *bZoomOut, *bZoom100, /**bZoomFit,*/ *bClose; + LWButtonSet buttonSet; + Glib::ustring cropLabel; + int backColor; + bool decorated; + + // 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 (to be confirmed) + 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; + + 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 drawSpotWBRectangle (Cairo::RefPtr cr); + void drawObservedFrame (Cairo::RefPtr cr, int rw=0, int rh=0); + void translateCoord (int phyx, int phyy, int& imgx, int& imgy); + void changeZoom (int zoom, bool notify=true, int centerx=-1, int centery=-1); + 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_); + virtual ~CropWindow (); + + void setDecorated (bool decorated) { this->decorated = decorated; } + void setFitZoomEnabled (bool fze) { fitZoomEnabled = fze; } + void setObservedCropWin (CropWindow* cw) { observedCropWin = cw; } + + 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); + + // 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 (); + 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 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); + 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 (); +}; + +#endif diff --git a/rtgui/cursormanager.cc b/rtgui/cursormanager.cc new file mode 100644 index 000000000..99bdb6701 --- /dev/null +++ b/rtgui/cursormanager.cc @@ -0,0 +1,104 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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"); + + 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); + + 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==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..4c0d1f446 --- /dev/null +++ b/rtgui/cursormanager.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 . + */ +#ifndef _CURSORMANAGER_ +#define _CURSORMANAGER_ + +#include + +enum CursorShape {CSArrow, CSOpenHand, CSClosedHand, CSMove, CSMoveLeft, CSMoveRight, CSResizeWidth, CSResizeHeight, CSResizeDiagonal, CSResizeTopLeft, CSResizeTopRight, CSResizeBottomLeft, CSResizeBottomRight, 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; + 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..7d8b9cf11 --- /dev/null +++ b/rtgui/curveeditor.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. + * + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 + +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::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; + } +} + +/* + * 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) { + + bgHistValid = 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; +} diff --git a/rtgui/curveeditor.h b/rtgui/curveeditor.h new file mode 100644 index 000000000..129d5b83b --- /dev/null +++ b/rtgui/curveeditor.h @@ -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 . + */ +#ifndef _CURVEEDITOR_ +#define _CURVEEDITOR_ + +#include "popuptogglebutton.h" +#include "../rtengine/LUT.h" +#include "coloredbar.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 { + + 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; + + 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; + 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(); +}; + + +/* + ******************** 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 paramCurveEd; + std::vector NURBSCurveEd; + 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); +}; + + +/* + ********************** 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; + 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 (); +}; + +#endif diff --git a/rtgui/curveeditorgroup.cc b/rtgui/curveeditorgroup.cc new file mode 100644 index 000000000..da795b26f --- /dev/null +++ b/rtgui/curveeditorgroup.cc @@ -0,0 +1,401 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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), cl(NULL) { + curveEditors.clear(); + displayedCurve = 0; + numberOfPackedCurve = 0; + flatSubGroup = 0; + diagonalSubGroup = 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 (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; + + // 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 (); + } +} + +/* + * 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->selected, displayedCurve->getIdentityValue())) { + 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; +} + +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("CURVEEDITOR_FILEDLGFILTERCURVE")); + filter_pp.add_pattern("*.rtc"); + dialog.add_filter(filter_pp); + + Gtk::FileFilter filter_any; + filter_any.set_name(M("CURVEEDITOR_FILEDLGFILTERANY")); + 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("CURVEEDITOR_FILEDLGFILTERCURVE")); + filter_pp.add_pattern("*.rtc"); + dialog.add_filter(filter_pp); + + Gtk::FileFilter filter_any; + filter_any.set_name(M("CURVEEDITOR_FILEDLGFILTERANY")); + 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..a14f2d28f --- /dev/null +++ b/rtgui/curveeditorgroup.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 _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 (); + void setUnChanged (bool uc, CurveEditor* ce); +}; + +class CurveEditorSubGroup { + + friend class CurveEditorGroup; + +private: + Glib::ustring& curveDir; + Glib::ustring lastFilename; + +protected: + int valLinear; + int valUnchanged; + CurveEditorGroup *parent; + + ColoredBar* leftBar; + ColoredBar* bottomBar; + + +public: + virtual ~CurveEditorSubGroup(); + int getValUnchanged() { return valUnchanged; } + int getValLinear() { return valLinear; } + virtual void updateBackgroundHistogram (CurveEditor* ce) {} + virtual void switchGUI() = 0; + virtual void refresh(CurveEditor *curveToRefresh) = 0; + +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 bool curveReset (int cType, double iValue) = 0; // Reset a curve editor, return TRUE if successful (curve changed) + 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..72980c5d2 --- /dev/null +++ b/rtgui/curvelistener.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 _CURVELISTENER_ +#define _CURVELISTENER_ + +class CurveEditor; + +class CurveListener { + + private: + bool multi; + public: + virtual void curveChanged () {} + virtual void curveChanged (CurveEditor* ce) {} + void setMulti(bool value) { multi = value; } + bool isMulti() { return multi; } + CurveListener() : multi(false) {} +}; + +#endif diff --git a/rtgui/darkframe.cc b/rtgui/darkframe.cc new file mode 100644 index 000000000..dfea06da1 --- /dev/null +++ b/rtgui/darkframe.cc @@ -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 . + */ +#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 () : Gtk::VBox(), FoldableToolPanel(this) +{ + set_border_width(4); + + hbdf = Gtk::manage(new Gtk::HBox()); + 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, 4); + hbdf->pack_start(*darkFrameFile); + hbdf->pack_start(*btnReset, Gtk::PACK_SHRINK, 4); + 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, 4); + pack_start( *dfAuto, Gtk::PACK_SHRINK, 4); + pack_start( *dfInfo, Gtk::PACK_SHRINK, 4); + + 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 ); +} + +void DarkFrame::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited) +{ + disableListener (); + dfautoconn.block(true); + + 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); + hbdf->set_sensitive( !pp->raw.df_autoselect ); + + lastDFauto = pp->raw.df_autoselect; + + if( pp->raw.df_autoselect && 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(""); + + dfAuto->set_active( pp->raw.df_autoselect ); + dfChanged = false; + + dfautoconn.block(false); + enableListener (); +} + +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; + //darkFrameFile->set_current_name(""); + darkFrameFile->set_filename (""); + + 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 100644 index 000000000..ef0c17206 --- /dev/null +++ b/rtgui/darkframe.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 _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; + // add other info here +}; + +class DarkFrame : public Gtk::VBox, 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; + +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..bba25eac9 --- /dev/null +++ b/rtgui/defringe.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 "defringe.h" +#include +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +Defringe::Defringe () : Gtk::VBox(), FoldableToolPanel(this) { + + set_border_width(4); + 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)) ); + } + + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); + enabled->set_active (false); + enabled->set_tooltip_markup (M("TP_SHARPENING_TOOLTIP")); + + enabled->show (); + pack_start (*enabled); + + Gtk::HSeparator *hsep1 = Gtk::manage (new Gtk::HSeparator()); + hsep1->show (); + pack_start (*hsep1); + + 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); + + enaConn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &Defringe::enabledChanged) ); + //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); +} + +Defringe::~Defringe () { + delete curveEditorPF; +} + +void Defringe::colorForValue (double valX, double valY, int callerId, ColorCaller *caller) { + + float R, G, B; + 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); + enabled->set_inconsistent (!pedited->defringe.enabled); + chshape->setUnChanged (!pedited->defringe.huecurve); + } + + enaConn.block (true); + enabled->set_active (pp->defringe.enabled); + enaConn.block (false); + + lastEnabled = 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 = enabled->get_active(); + pp->defringe.huecurve = chshape->getCurve (); + + if (pedited) { + pedited->defringe.radius = radius->getEditedState (); + pedited->defringe.threshold = threshold->getEditedState (); + pedited->defringe.enabled = !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 && enabled->get_active()) listener->panelChanged (EvPFCurve, M("HISTORY_CUSTOMCURVE")); +} + +void Defringe::adjusterChanged (Adjuster* a, double newval) { + + if (listener && enabled->get_active()) { + + 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 (batchMode) { + if (enabled->get_inconsistent()) { + enabled->set_inconsistent (false); + enaConn.block (true); + enabled->set_active (false); + enaConn.block (false); + } + else if (lastEnabled) + enabled->set_inconsistent (true); + + lastEnabled = enabled->get_active (); + } + + if (listener) { + if (enabled->get_active ()) + 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..9edbe644c --- /dev/null +++ b/rtgui/defringe.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 . + */ +#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 Gtk::VBox, public AdjusterListener, public FoldableToolPanel, public CurveListener, public ColorProvider{ + + protected: + CurveEditorGroup* curveEditorPF; + FlatCurveEditor* chshape; + + Adjuster* radius; + Adjuster* threshold; + Gtk::CheckButton* enabled; + bool lastEnabled; + sigc::connection enaConn; + 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, int callerId, ColorCaller* caller); + +}; + +#endif diff --git a/rtgui/diagonalcurveeditorsubgroup.cc b/rtgui/diagonalcurveeditorsubgroup.cc new file mode 100644 index 000000000..12a822a1c --- /dev/null +++ b/rtgui/diagonalcurveeditorsubgroup.cc @@ -0,0 +1,727 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 "curveeditor.h" +#include "diagonalcurveeditorsubgroup.h" + +DiagonalCurveEditorSubGroup::DiagonalCurveEditorSubGroup (CurveEditorGroup* prt, Glib::ustring& curveDir) : CurveEditorSubGroup(curveDir) { + + valLinear = (int)DCT_Linear; + valUnchanged = (int)DCT_Unchanged; + parent = prt; + + activeParamControl = -1; + + // custom curve + customCurveBox = new Gtk::VBox (); + customCurveBox->set_spacing(4); + customCurve = Gtk::manage (new MyDiagonalCurve ()); + customCurve->set_size_request (GRAPH_SIZE+2*RADIUS, GRAPH_SIZE+2*RADIUS); + customCurve->setType (DCT_Spline); + //customCurve->set_tooltip_text (M("CURVEEDITOR_TOOLTIPMOVESPEED")); + customCurveBox->pack_start (*customCurve, Gtk::PACK_EXPAND_WIDGET, 0); + + Gtk::HBox* 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"))); + + 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); + + customCurveBox->pack_end (*custombbox, Gtk::PACK_SHRINK, 0); + customCurveBox->show_all (); + + 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) ); + + 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); + NURBSCurve = Gtk::manage (new MyDiagonalCurve ()); + NURBSCurve->set_size_request (GRAPH_SIZE+2*RADIUS, GRAPH_SIZE+2*RADIUS); + NURBSCurve->setType (DCT_NURBS); + + //customCurve->set_tooltip_text (M("CURVEEDITOR_TOOLTIPMOVESPEED")); + NURBSCurveBox->pack_start (*NURBSCurve, Gtk::PACK_EXPAND_WIDGET, 0); + + Gtk::HBox* 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"))); + + 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); + + NURBSCurveBox->pack_end (*NURBSbbox, Gtk::PACK_SHRINK, 0); + NURBSCurveBox->show_all (); + + 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) ); + + 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(0); + + paramCurve = Gtk::manage (new MyDiagonalCurve ()); + paramCurve->set_size_request (GRAPH_SIZE+2*RADIUS, GRAPH_SIZE+2*RADIUS); + paramCurve->setType (DCT_Parametric); + + shcSelector = Gtk::manage (new SHCSelector ()); + shcSelector->set_size_request (GRAPH_SIZE-100, 12); // width, height + //* shcSelector->set_size_request ((GRAPH_SIZE+2*RADIUS)-20, 20); + + paramCurveBox->pack_start (*paramCurve, Gtk::PACK_EXPAND_WIDGET, 0); + paramCurveBox->pack_start (*shcSelector, Gtk::PACK_EXPAND_WIDGET, 0); + + Gtk::HBox* Parambbox = Gtk::manage (new Gtk::HBox ()); + Parambbox->set_spacing(4); + 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"))); + + 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); + + 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) ); + + 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")); + + paramCurveBox->pack_end (*Parambbox, Gtk::PACK_EXPAND_WIDGET, 0); + + 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); + + paramCurveBox->pack_start (*evhighlights); + paramCurveBox->pack_start (*evlights); + paramCurveBox->pack_start (*evdarks); + paramCurveBox->pack_start (*evshadows); + + 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; +} + +/* + * 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(); + 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(); + parent->pack_start (*paramCurveBox); + break; + } + case (DCT_NURBS): + NURBSCurve->setPoints (dCurve->NURBSCurveEd); + NURBSCurve->setColorProvider(dCurve->getCurveColorProvider(), dCurve->getCurveCallerId()); + NURBSCurve->setColoredBar(leftBar, bottomBar); + NURBSCurve->forceResize(); + 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; +} + + +/* + * 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(int cType, double iValue) { + switch ((DiagonalCurveType) cType) { + case (DCT_NURBS) : // = Control cage + NURBSCurve->reset (); + return true; + break; + case (DCT_Spline) : // = Custom + customCurve->reset (); + 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 (); + 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..71a46e959 --- /dev/null +++ b/rtgui/diagonalcurveeditorsubgroup.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 _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; + + Gtk::Button* saveCustom; + Gtk::Button* loadCustom; + Gtk::Button* copyCustom; + Gtk::Button* pasteCustom; + Gtk::Button* saveNURBS; + Gtk::Button* loadNURBS; + Gtk::Button* copyNURBS; + Gtk::Button* pasteNURBS; + Gtk::Button* saveParam; + Gtk::Button* loadParam; + Gtk::Button* copyParam; + Gtk::Button* pasteParam; + + 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); + +protected: + void storeCurveValues (CurveEditor* ce, const std::vector& p); + void storeDisplayedCurve (); + void restoreDisplayedHistogram (); + void savePressed (); + void loadPressed (); + void copyPressed (); + void pastePressed (); + bool curveReset (int cType, double iValue); + 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..502a620a2 --- /dev/null +++ b/rtgui/dirbrowser.cc @@ -0,0 +1,372 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 "../rtengine/safegtk.h" + +#include +#include "guiutils.h" +#include "rtimage.h" + +#define CHECKTIME 5000 + +DirBrowser::DirBrowser () : 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(false); + 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", 1); + tvc.add_attribute(*render_pb, "pixbuf", 1); + tvc.add_attribute(*render_pb, "pixbuf-expander-open", 0); + tvc.pack_start (crt); + tvc.add_attribute(crt, "text", 2); + + crt.property_ypad() = 0; + render_pb->property_ypad() = 0; + + dirtree->append_column(tvc); + + dirtree->signal_row_expanded().connect(sigc::mem_fun(*this, &DirBrowser::row_expanded)); + dirtree->signal_row_activated().connect(sigc::mem_fun(*this, &DirBrowser::row_activated)); +} + +#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::row_expanded (const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path) { + + expandSuccess = false; + + int todel = iter->children().size(); + + std::vector 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 { + + std::sort (subDirs.begin(), subDirs.end()); + for (size_t i=0; ierase (iter->children().begin()); + 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 (0, openfolder); + child->set_value (1, 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..c1a3a9a68 --- /dev/null +++ b/rtgui/dirbrowser.h @@ -0,0 +1,103 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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); } + }; + + Gtk::TreeViewColumn tvc; + Gtk::CellRendererText crt; + Gtk::CellRendererPixbuf crb; + DirTreeColumns dtColumns; + + 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 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..851549dc8 --- /dev/null +++ b/rtgui/dirpyrdenoise.cc @@ -0,0 +1,343 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 + +using namespace rtengine; +using namespace rtengine::procparams; + +DirPyrDenoise::DirPyrDenoise () : Gtk::VBox(), FoldableToolPanel(this) { + + set_border_width(4); + + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); + enabled->set_tooltip_text (M("TP_DIRPYRDENOISE_ENABLED_TOOLTIP")); + + enabled->set_active (false); + enabled->show (); + pack_start (*enabled); + + Gtk::HSeparator *hsep1 = Gtk::manage (new Gtk::HSeparator()); + hsep1->show (); + pack_start (*hsep1); + + enaConn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &DirPyrDenoise::enabledChanged) ); + + + 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)); + 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_RGB")); + dmethod->append_text (M("TP_DIRPYRDENOISE_LAB")); + dmethod->set_active(0); + hb1->pack_end (*dmethod, Gtk::PACK_EXPAND_WIDGET, 4); + pack_start( *hb1, Gtk::PACK_SHRINK, 4); + + +// perform = Gtk::manage (new Gtk::CheckButton (M("TP_DIRPYRDENOISE_PERF"))); +// perform->set_tooltip_text (M("TP_DIRPYRDENOISE_PERF_TOOLTIP")); + +// perfconn = perform->signal_toggled().connect( sigc::mem_fun(*this, &DirPyrDenoise::perform_toggled) ); + 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); + + gamma->setAdjusterListener (this); + + luma->show(); + Ldetail->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")); + + + pack_start (*luma); + pack_start (*Ldetail); + pack_start (*chroma); + pack_start (*redchro); + pack_start (*bluechro); + + pack_start (*gamma); + pack_start (*enhance); + +// pack_start (*perform); + enhanConn = enhance->signal_toggled().connect( sigc::mem_fun(*this, &DirPyrDenoise::enhanceChanged) ); + +} + +void DirPyrDenoise::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + dmethodconn.block(true); + enaConn.block (true); + + dmethod->set_active (0); + if (pp->dirpyrDenoise.dmethod=="RGB") + dmethod->set_active (0); + else if (pp->dirpyrDenoise.dmethod=="Lab") + dmethod->set_active (1); + + if (pedited) { + if (!pedited->dirpyrDenoise.dmethod) + dmethod->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); + enabled->set_inconsistent (!pedited->dirpyrDenoise.enabled); + enhance->set_inconsistent (!pedited->dirpyrDenoise.enhance); + // perform->set_inconsistent (!pedited->dirpyrDenoise.perform); + } +// perfconn.block (true); + enabled->set_active (pp->dirpyrDenoise.enabled); + enhance->set_active (pp->dirpyrDenoise.enhance); + // perform->set_active (pp->dirpyrDenoise.perform); + + // perfconn.block (false); + lastEnabled = pp->dirpyrDenoise.enabled; + 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); + + enaConn.block (false); + dmethodconn.block(false); + enableListener (); +} + +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.enabled = enabled->get_active(); + pp->dirpyrDenoise.enhance = enhance->get_active(); +// pp->dirpyrDenoise.perform = perform->get_active(); + + if (pedited) { + pedited->dirpyrDenoise.dmethod = dmethod->get_active_row_number() != 2; + 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.enabled = !enabled->get_inconsistent(); + pedited->dirpyrDenoise.enhance = !enhance->get_inconsistent(); + // pedited->dirpyrDenoise.perform = !perform->get_inconsistent(); + } + if (dmethod->get_active_row_number()==0) + pp->dirpyrDenoise.dmethod = "RGB"; + else if (dmethod->get_active_row_number()==1) + pp->dirpyrDenoise.dmethod = "Lab"; +} + +void DirPyrDenoise::dmethodChanged () { + + if (listener && (multiImage||enabled->get_active()) ) { + listener->panelChanged (EvDPDNmet, dmethod->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); + + 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); + } + else { + luma->setDefaultEditedState (Irrelevant); + Ldetail->setDefaultEditedState (Irrelevant); + chroma->setDefaultEditedState (Irrelevant); + redchro->setDefaultEditedState (Irrelevant); + bluechro->setDefaultEditedState (Irrelevant); + gamma->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 && enabled->get_active()) { + 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); + } +} + +void DirPyrDenoise::enabledChanged () { + + if (batchMode) { + if (enabled->get_inconsistent()) { + enabled->set_inconsistent (false); + enaConn.block (true); + enabled->set_active (false); + enaConn.block (false); + } + else if (lastEnabled) + enabled->set_inconsistent (true); + + lastEnabled = enabled->get_active (); + } + + if (listener) { + if (enabled->get_active ()) + 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::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 (); + dmethod->append_text (M("GENERAL_UNCHANGED")); +} + +void DirPyrDenoise::setAdjusterBehavior (bool lumaadd, bool lumdetadd, bool chromaadd, bool chromaredadd, bool chromablueadd, bool gammaadd) { + + luma->setAddMode(lumaadd); + Ldetail->setAddMode(lumdetadd); + chroma->setAddMode(chromaadd); + redchro->setAddMode(chromaredadd); + bluechro->setAddMode(chromablueadd); + gamma->setAddMode(gammaadd); +} + +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); +} diff --git a/rtgui/dirpyrdenoise.h b/rtgui/dirpyrdenoise.h new file mode 100644 index 000000000..c0506d44a --- /dev/null +++ b/rtgui/dirpyrdenoise.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 _DIRPYRDENOISE_H_ +#define _DIRPYRDENOISE_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" + +class DirPyrDenoise : public Gtk::VBox, public AdjusterListener, public FoldableToolPanel { + + protected: + Adjuster* luma; + Adjuster* Ldetail; + Adjuster* chroma; + Adjuster* redchro; + Adjuster* bluechro; + Adjuster* gamma; + + Gtk::CheckButton* enabled; + bool lastEnabled; + sigc::connection enaConn; + Gtk::CheckButton* enhance; + bool lastenhance; + sigc::connection enhanConn; + +// Gtk::CheckButton* perform; +// bool lastperform; +// sigc::connection perfconn; + MyComboBoxText* dmethod; + sigc::connection dmethodconn; + + + public: + + 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 adjusterChanged (Adjuster* a, double newval); + void enabledChanged (); + void enhanceChanged (); +// void perform_toggled (); + void dmethodChanged (); + + void setAdjusterBehavior (bool lumaadd, bool lumdetadd, bool chromaadd, bool chromaredadd, bool chromablueadd, bool gammaadd); + void trimValues (rtengine::procparams::ProcParams* pp); +}; + +#endif diff --git a/rtgui/dirpyrequalizer.cc b/rtgui/dirpyrequalizer.cc new file mode 100644 index 000000000..80942bf95 --- /dev/null +++ b/rtgui/dirpyrequalizer.cc @@ -0,0 +1,249 @@ +/* + * 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 () : Gtk::VBox(), FoldableToolPanel(this) { + + set_border_width(4); + + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); + enabled->set_active (true); + pack_start(*enabled); + enaConn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &DirPyrEqualizer::enabledToggled) ); + enabled->set_tooltip_markup (M("TP_SHARPENING_TOOLTIP")); + + Gtk::HSeparator *separator1 = Gtk::manage (new Gtk::HSeparator()); + pack_start(*separator1, Gtk::PACK_SHRINK, 2); + + Gtk::HBox * buttonBox1 = Gtk::manage (new Gtk::HBox()); + pack_start(*buttonBox1, Gtk::PACK_SHRINK, 2); + + Gtk::Button * lumacontrastMinusButton = Gtk::manage (new Gtk::Button(M("TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS"))); + buttonBox1->pack_start(*lumacontrastMinusButton, Gtk::PACK_SHRINK, 2); + 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, Gtk::PACK_SHRINK, 2); + 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, Gtk::PACK_SHRINK, 2); + 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 < 5; i++) + { + Glib::ustring ss; + ss = Glib::ustring::format(i); + if (i == 0) ss += Glib::ustring::compose(" (%1)", M("TP_DIRPYREQUALIZER_LUMAFINEST")); + else if(i == 4) 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); + + show_all_children (); + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +} + +DirPyrEqualizer::~DirPyrEqualizer () { + +} + +void DirPyrEqualizer::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + if (pedited) { + + enabled->set_inconsistent (!pedited->dirpyrequalizer.enabled); + + for(int i = 0; i < 5; i++) { + multiplier[i]->setEditedState (pedited->dirpyrequalizer.mult[i] ? Edited : UnEdited); + } + threshold->setEditedState (pedited->dirpyrequalizer.threshold ? Edited : UnEdited); + } + + enaConn.block (true); + enabled->set_active (pp->dirpyrequalizer.enabled); + enaConn.block (false); + lastEnabled = pp->dirpyrequalizer.enabled; + + for (int i = 0; i < 5; i++) { + multiplier[i]->setValue(pp->dirpyrequalizer.mult[i]); + } + threshold->setValue(pp->dirpyrequalizer.threshold); + + enableListener (); +} + +void DirPyrEqualizer::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->dirpyrequalizer.enabled = enabled->get_active (); + + for (int i = 0; i < 5; i++) { + pp->dirpyrequalizer.mult[i] = multiplier[i]->getValue(); + } + pp->dirpyrequalizer.threshold = threshold->getValue(); + + if (pedited) { + + pedited->dirpyrequalizer.enabled = !enabled->get_inconsistent(); + + for(int i = 0; i < 5; i++) { + pedited->dirpyrequalizer.mult[i] = multiplier[i]->getEditedState(); + } + pedited->dirpyrequalizer.threshold = threshold->getEditedState(); + } +} + +void DirPyrEqualizer::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + for (int i = 0; i < 5; i++) { + multiplier[i]->setDefault(defParams->dirpyrequalizer.mult[i]); + } + threshold->setDefault(defParams->dirpyrequalizer.threshold); + + if (pedited) { + for (int i = 0; i < 5; i++) { + multiplier[i]->setDefaultEditedState(pedited->dirpyrequalizer.mult[i] ? Edited : UnEdited); + } + threshold->setDefaultEditedState(pedited->dirpyrequalizer.threshold ? Edited : UnEdited); + } + else { + for (int i = 0; i < 5; i++) { + multiplier[i]->setDefaultEditedState(Irrelevant); + } + threshold->setDefaultEditedState(Irrelevant); + } +} + +void DirPyrEqualizer::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + + for (int i = 0; i < 5; i++) { + multiplier[i]->showEditedCB(); + } + threshold->showEditedCB(); +} + +void DirPyrEqualizer::adjusterChanged (Adjuster* a, double newval) { + + if (listener && enabled->get_active()) { + if (a == threshold) { + listener->panelChanged (EvDirPyrEqualizerThreshold, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(2), threshold->getValue())) + ); + } + else { + listener->panelChanged (EvDirPyrEqualizer, + Glib::ustring::compose("%1, %2, %3, %4, %5", + 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())) + ); + } + } +} + +void DirPyrEqualizer::enabledToggled () { + + if (batchMode) { + if (enabled->get_inconsistent()) { + enabled->set_inconsistent (false); + enaConn.block (true); + enabled->set_active (false); + enaConn.block (false); + } + else if (lastEnabled) + enabled->set_inconsistent (true); + + lastEnabled = enabled->get_active (); + } + + if (listener) { + if (enabled->get_active ()) + listener->panelChanged (EvDirPyrEqlEnabled, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvDirPyrEqlEnabled, M("GENERAL_DISABLED")); + } +} + + +void DirPyrEqualizer::lumaneutralPressed () { + + for (int i = 0; i < 5; i++) { + multiplier[i]->setValue(1.0); + adjusterChanged(multiplier[i], 1.0); + } +} + + +void DirPyrEqualizer::lumacontrastPlusPressed () { + + for (int i = 0; i < 5; i++) { + float inc = 0.05 * (5 - i); + multiplier[i]->setValue(multiplier[i]->getValue() + inc); + adjusterChanged(multiplier[i], multiplier[i]->getValue()); + } +} + + +void DirPyrEqualizer::lumacontrastMinusPressed () { + + for (int i = 0; i < 5; i++) { + float inc = -0.05 * (5 - i); + multiplier[i]->setValue(multiplier[i]->getValue() + inc); + adjusterChanged(multiplier[i], multiplier[i]->getValue()); + } +} + +void DirPyrEqualizer::setAdjusterBehavior (bool multiplieradd, bool thresholdadd) { + + for (int i=0; i<5; i++) + multiplier[i]->setAddMode(multiplieradd); + threshold->setAddMode(thresholdadd); +} + +void DirPyrEqualizer::trimValues (rtengine::procparams::ProcParams* pp) { + + for (int i=0; i<5; i++) + multiplier[i]->trimValue(pp->dirpyrequalizer.mult[i]); + threshold->trimValue(pp->dirpyrequalizer.threshold); +} diff --git a/rtgui/dirpyrequalizer.h b/rtgui/dirpyrequalizer.h new file mode 100644 index 000000000..60783f92f --- /dev/null +++ b/rtgui/dirpyrequalizer.h @@ -0,0 +1,62 @@ +/* + * 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" + +class DirPyrEqualizer : public Gtk::VBox, public AdjusterListener, public FoldableToolPanel +{ + +protected: + + Gtk::CheckButton * enabled; + Adjuster* multiplier[5]; + Adjuster* threshold; + + sigc::connection enaConn; + sigc::connection lumaneutralPressedConn; + sigc::connection lumacontrastPlusPressedConn; + sigc::connection lumacontrastMinusPressedConn; + + bool lastEnabled; + +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); + void trimValues (rtengine::procparams::ProcParams* pp); + + void adjusterChanged (Adjuster* a, double newval); + void enabledToggled (); + 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..1c3318b2e --- /dev/null +++ b/rtgui/distortion.cc @@ -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 . + */ +#include "distortion.h" +#include +#include "rtimage.h" + +extern Glib::ustring argv0; + +using namespace rtengine; +using namespace rtengine::procparams; + +Distortion::Distortion (): Gtk::VBox(), FoldableToolPanel(this) { + + set_border_width(4); + + 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..1d7c9b92a --- /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 Gtk::VBox, 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/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..22631b10f --- /dev/null +++ b/rtgui/editenums.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 _EDITENUMS_ +#define _EDITENUMS_ + +enum ImgEditState {SNormal, SCropMove, SHandMove, SResizeW1, SResizeW2, SResizeH1, SResizeH2, SResizeTL, SResizeTR, SResizeBL, SResizeBR, SCropSelecting, SRotateSelecting, SCropWinMove, SCropFrameMove, SCropImgMove, SCropWinResize, SObservedMove}; +enum CursorArea {CropWinButtons, CropToolBar, CropImage, CropBorder, CropTop, CropTopLeft, CropTopRight, CropBottom, CropBottomLeft, CropBottomRight, CropLeft, CropRight, CropInside, CropResize, CropObserved}; + +#endif diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc new file mode 100755 index 000000000..c02bc6edb --- /dev/null +++ b/rtgui/editorpanel.cc @@ -0,0 +1,1626 @@ +/* + * 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) + : beforePreviewHandler(NULL), beforeIarea(NULL), parent(NULL), ipc(NULL), beforeIpc(NULL), isProcessing(false), catalogPane(NULL) { + + epih = new EditorPanelIdleHelper; + epih->epanel = this; + epih->destroyed = false; + epih->pending = 0; + + 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 (); + + 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); + + if (options.showProfileSelector) 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); + + // 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")); + + if (!simpleEditor && !options.tabbedUI){ + 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) ); + navPrev->signal_pressed().connect( sigc::mem_fun(*this, &EditorPanel::openPreviousEditorImage) ); + navNext->signal_pressed().connect( sigc::mem_fun(*this, &EditorPanel::openNextEditorImage) ); + 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; + +} + +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::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 () { + + Gtk::VBox::on_realize (); + // This line is needed to avoid autoexpansion of the window :-/ + vboxright->set_size_request (options.toolPanelWidth, -1); +} + +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 (); + + 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); + 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 + if (!options.tabbedUI) 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 () { + + return Glib::path_get_basename (openThm->getFileName ()); +} + +Glib::ustring EditorPanel::getFileName () { + + return openThm->getFileName (); +} + +// 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; + EditorPanelIdleHelper* epih; +}; + +void EditorPanel::displayError (Glib::ustring descr) { + + if (parent) { + Gtk::MessageDialog* msgd = new Gtk::MessageDialog (*parent, descr, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); + msgd->set_title (M("MAIN_MSG_CANNOTSAVE")); + msgd->run (); + delete 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->descr); + p->epih->pending--; + delete p; + + return 0; +} + +void EditorPanel::error (Glib::ustring descr) { + + epih->pending++; + errparams* p = new errparams; + p->descr = descr; + 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); + } + else { + catalogPane->hide(); + tbTopPanel_1->set_image (*iTopPanel_1_Show); + } + + 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: + iareapanel->imageArea->zoomPanel->zoomInClicked(); + return true; + case GDK_minus: + case GDK_underscore: + 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; + } + } + + 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); + + } + 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 { + Glib::ustring msg_ = Glib::ustring("") + fname + ": Error during image saving\n"; + Gtk::MessageDialog msgd (*parent, msg_, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); + msgd.run (); + } + + saveimgas->set_sensitive(true); + sendtogimp->set_sensitive(true); + + parent->setProgressStr(""); + parent->setProgress(0.); + + setProgressState(false); + + delete pc; + 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) { + // 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 ), + 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 ), + sigc::bind(sigc::mem_fun( *this,&EditorPanel::idle_sendToGimp ),ld )); + 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){ + + rtengine::IImage16* img = pc->returnValue(); + delete pc; + if (img) { + // get file name base + Glib::ustring shortname = removeExtension (Glib::path_get_basename (openThm->getFileName())); + 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::updateProfileSelector (bool showMe) { + if (showMe) { + // add the profile panel + vboxright->pack_start (*ppframe, Gtk::PACK_SHRINK, 2); + vboxright->reorder_child(*ppframe, 0 + (options.histogramPosition==2?1:0)); + ppframe->show_all(); + } + else { + // remove (but don't delete) the profile panel + removeIfThere(vboxright, ppframe, false); + } +} + +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..5ab7319ab --- /dev/null +++ b/rtgui/editorpanel.h @@ -0,0 +1,205 @@ +/* + * 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; + + 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 + 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); + 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(); + + // progresslistener interface + void setProgress (double p); + void setProgressStr (Glib::ustring str); + void setProgressState (bool inProcessing); + void error (Glib::ustring descr); + void displayError (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 updateProfileSelector(bool showMe); + 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..6a67e2b51 --- /dev/null +++ b/rtgui/editwindow.cc @@ -0,0 +1,225 @@ +/* +* 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(monNo==0 ? 1:0, 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("RawTherapee "+ M("EDITWINDOW_TITLE")); + 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)); + 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 (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); + + epanels[ name ] = ep; + filesEdited.insert ( name ); + parent->fpanel->refreshEditedState (filesEdited); + ep->setAspect(); +} + +void EditWindow::remEditorPanel (EditorPanel* ep) { + epanels.erase (ep->getShortName()); + filesEdited.erase (ep->getShortName ()); + parent->fpanel->refreshEditedState (filesEdited); + + mainNB->remove_page (*ep); + // 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)); + 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 false; + + + 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 true; +} + diff --git a/rtgui/editwindow.h b/rtgui/editwindow.h new file mode 100644 index 000000000..6f57f5506 --- /dev/null +++ b/rtgui/editwindow.h @@ -0,0 +1,58 @@ +/* + * 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 on_realize (); +}; + +#endif diff --git a/rtgui/epd.cc b/rtgui/epd.cc new file mode 100644 index 000000000..78c25952e --- /dev/null +++ b/rtgui/epd.cc @@ -0,0 +1,167 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 () : Gtk::VBox(), FoldableToolPanel(this){ + + set_border_width(4); + + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); + enabled->set_active (false); + enabled->set_tooltip_markup (M("TP_EPD_TOOLTIP")); + enabled->show (); + pack_start (*enabled); + + Gtk::HSeparator *hsep1 = Gtk::manage (new Gtk::HSeparator()); + hsep1->show (); + pack_start (*hsep1); + + enaConn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &EdgePreservingDecompositionUI::enabledChanged) ); + + Strength = Gtk::manage(new Adjuster (M("TP_EPD_STRENGTH"), -2.0, 2.0, 0.01, 0.25)); + EdgeStopping = Gtk::manage(new Adjuster (M("TP_EPD_EDGESTOPPING"), 0.1, 4.0, 0.01, 1.4)); + Scale = Gtk::manage(new Adjuster (M("TP_EPD_SCALE"), 0.1, 10.0, 0.01, 1.0)); + ReweightingIterates = Gtk::manage(new Adjuster (M("TP_EPD_REWEIGHTINGITERATES"), 0, 9, 1, 0)); + + Strength->setAdjusterListener(this); + EdgeStopping->setAdjusterListener(this); + Scale->setAdjusterListener(this); + ReweightingIterates->setAdjusterListener(this); + + Strength->show(); + EdgeStopping->show(); + Scale->show(); + ReweightingIterates->show(); + + pack_start(*Strength); + pack_start(*EdgeStopping); + pack_start(*Scale); + pack_start(*ReweightingIterates); +} + +void EdgePreservingDecompositionUI::read(const ProcParams *pp, const ParamsEdited *pedited){ + disableListener(); + + if(pedited){ + Strength->setEditedState(pedited->edgePreservingDecompositionUI.Strength ? Edited : UnEdited); + EdgeStopping->setEditedState(pedited->edgePreservingDecompositionUI.EdgeStopping ? Edited : UnEdited); + Scale->setEditedState(pedited->edgePreservingDecompositionUI.Scale ? Edited : UnEdited); + ReweightingIterates->setEditedState(pedited->edgePreservingDecompositionUI.ReweightingIterates ? Edited : UnEdited); + + enabled->set_inconsistent(!pedited->edgePreservingDecompositionUI.enabled); + } + + enaConn.block(true); + enabled->set_active(pp->edgePreservingDecompositionUI.enabled); + enaConn.block (false); + + lastEnabled = pp->edgePreservingDecompositionUI.enabled; + + Strength->setValue(pp->edgePreservingDecompositionUI.Strength); + EdgeStopping->setValue(pp->edgePreservingDecompositionUI.EdgeStopping); + Scale->setValue(pp->edgePreservingDecompositionUI.Scale); + ReweightingIterates->setValue(pp->edgePreservingDecompositionUI.ReweightingIterates); + + enableListener(); +} + +void EdgePreservingDecompositionUI::write(ProcParams *pp, ParamsEdited *pedited){ + pp->edgePreservingDecompositionUI.Strength = Strength->getValue(); + pp->edgePreservingDecompositionUI.EdgeStopping = EdgeStopping->getValue(); + pp->edgePreservingDecompositionUI.Scale = Scale->getValue(); + pp->edgePreservingDecompositionUI.ReweightingIterates = ReweightingIterates->getValue(); + pp->edgePreservingDecompositionUI.enabled = enabled->get_active(); + + if(pedited){ + pedited->edgePreservingDecompositionUI.Strength = Strength->getEditedState(); + pedited->edgePreservingDecompositionUI.EdgeStopping = EdgeStopping->getEditedState(); + pedited->edgePreservingDecompositionUI.Scale = Scale->getEditedState(); + pedited->edgePreservingDecompositionUI.ReweightingIterates = ReweightingIterates->getEditedState(); + pedited->edgePreservingDecompositionUI.enabled = !enabled->get_inconsistent(); + } +} + +void EdgePreservingDecompositionUI::setDefaults(const ProcParams *defParams, const ParamsEdited *pedited){ + Strength->setDefault(defParams->edgePreservingDecompositionUI.Strength); + EdgeStopping->setDefault(defParams->edgePreservingDecompositionUI.EdgeStopping); + Scale->setDefault(defParams->edgePreservingDecompositionUI.Scale); + ReweightingIterates->setDefault(defParams->edgePreservingDecompositionUI.ReweightingIterates); + + if(pedited){ + Strength->setDefaultEditedState(pedited->edgePreservingDecompositionUI.Strength ? Edited : UnEdited); + EdgeStopping->setDefaultEditedState(pedited->edgePreservingDecompositionUI.EdgeStopping ? Edited : UnEdited); + Scale->setDefaultEditedState(pedited->edgePreservingDecompositionUI.Scale ? Edited : UnEdited); + ReweightingIterates->setDefaultEditedState(pedited->edgePreservingDecompositionUI.ReweightingIterates ? Edited : UnEdited); + }else{ + Strength->setDefaultEditedState(Irrelevant); + EdgeStopping->setDefaultEditedState(Irrelevant); + Scale->setDefaultEditedState(Irrelevant); + ReweightingIterates->setDefaultEditedState(Irrelevant); + } +} + +void EdgePreservingDecompositionUI::adjusterChanged(Adjuster* a, double newval){ + if(listener && enabled->get_active()){ + if(a == Strength) + listener->panelChanged(EvEPDStrength, 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(batchMode){ + if(enabled->get_inconsistent()){ + enabled->set_inconsistent (false); + enaConn.block (true); + enabled->set_active (false); + enaConn.block (false); + } + else if(lastEnabled) + enabled->set_inconsistent (true); + + lastEnabled = enabled->get_active (); + } + + if(listener){ + if(enabled->get_active ()) + listener->panelChanged (EvEPDEnabled, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvEPDEnabled, M("GENERAL_DISABLED")); + } +} + +void EdgePreservingDecompositionUI::setBatchMode(bool batchMode){ + ToolPanel::setBatchMode(batchMode); + + Strength->showEditedCB(); + EdgeStopping->showEditedCB(); + Scale->showEditedCB(); + ReweightingIterates->showEditedCB(); +} + diff --git a/rtgui/epd.h b/rtgui/epd.h new file mode 100644 index 000000000..6ae32f4bf --- /dev/null +++ b/rtgui/epd.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 _EPD_H_ +#define _EPD_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" + +class EdgePreservingDecompositionUI : public Gtk::VBox, public AdjusterListener, public FoldableToolPanel { +protected: + Adjuster *Strength; + Adjuster *EdgeStopping; + Adjuster *Scale; + Adjuster *ReweightingIterates; + + Gtk::CheckButton* enabled; + bool lastEnabled; + sigc::connection enaConn; + +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..13c78e148 --- /dev/null +++ b/rtgui/exportpanel.cc @@ -0,0 +1,415 @@ +/* + * 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_raw_all_enhance = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_RAW_ALL_ENHANCE"))); + bypass_raw_ccSteps = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_RAW_CCSTEPS"))); + bypass_raw_linenoise = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_RAW_LINENOISE"))); + bypass_raw_greenthresh = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_RAW_GREENTHRESH"))); + bypass_raw_ca = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_RAW_CA"))); + bypass_raw_df = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_RAW_DF"))); + bypass_raw_ff = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_RAW_FF"))); + bypass_raw_dcb_iterations = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_RAW_DCB_ITERATIONS"))); + bypass_raw_dcb_enhance = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_RAW_DCB_ENHANCE"))); + bypass_raw_lmmse_iterations = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_RAW_LMMSE_ITERATIONS"))); + + Gtk::HBox* hb_raw_dmethod = Gtk::manage (new Gtk::HBox ()); + hb_raw_dmethod->pack_start (*Gtk::manage (new Gtk::Label ( M("EXPORT_RAW_DMETHOD") +": ")),Gtk::PACK_SHRINK, 4); + raw_dmethod = Gtk::manage (new MyComboBoxText ()); + for( size_t i=0; i< procparams::RAWParams::numMethods;i++) + raw_dmethod->append_text(procparams::RAWParams::methodstring[i]); + + raw_dmethod->set_active(0); + hb_raw_dmethod->pack_end (*raw_dmethod, Gtk::PACK_EXPAND_WIDGET, 4); + + // start 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(*hb_raw_dmethod , Gtk::PACK_SHRINK, 4); + //pack_start(*bypass_raw_all_enhance , Gtk::PACK_SHRINK, 4); + pack_start(*bypass_raw_ccSteps , Gtk::PACK_SHRINK, 4); + pack_start(*bypass_raw_dcb_iterations, Gtk::PACK_SHRINK, 4); + pack_start(*bypass_raw_dcb_enhance , Gtk::PACK_SHRINK, 4); + pack_start(*bypass_raw_ca , Gtk::PACK_SHRINK, 4); + pack_start(*bypass_raw_lmmse_iterations, Gtk::PACK_SHRINK, 4); + + pack_start(*bypass_raw_linenoise , Gtk::PACK_SHRINK, 4); + pack_start(*bypass_raw_greenthresh , 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 + + resize_method = Gtk::manage (new MyComboBoxText ()); + resize_method->append_text (M("TP_RESIZE_NEAREST")); + resize_method->append_text (M("TP_RESIZE_BILINEAR")); + resize_method->append_text (M("TP_RESIZE_BICUBIC")); + resize_method->append_text (M("TP_RESIZE_BICUBICSF")); + resize_method->append_text (M("TP_RESIZE_BICUBICSH")); + resize_method->append_text (M("TP_RESIZE_LANCZOS")); + resize_method->set_active (5); + + Gtk::HBox* rmbox = Gtk::manage (new Gtk::HBox ()); + rmbox->pack_start (*Gtk::manage (new Gtk::Label (M("EXPORT_RESIZEMETHOD"))), Gtk::PACK_SHRINK, 4); + rmbox->pack_start (*resize_method); + 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_raw_all_enhanceConn = bypass_raw_all_enhance->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_dcb_iterationsConn = bypass_raw_dcb_iterations->signal_toggled().connect (sigc::bind (sigc::mem_fun(*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); + bypass_raw_dcb_enhanceConn = bypass_raw_dcb_enhance->signal_toggled().connect (sigc::bind (sigc::mem_fun(*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); + bypass_raw_lmmse_iterationsConn = bypass_raw_lmmse_iterations->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_linenoiseConn = bypass_raw_linenoise->signal_toggled().connect (sigc::bind (sigc::mem_fun(*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); + bypass_raw_greenthreshConn = bypass_raw_greenthresh->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_raw_all_enhance = bypass_raw_all_enhance->get_active (); + options.fastexport_bypass_raw_ccSteps = bypass_raw_ccSteps->get_active (); + options.fastexport_bypass_raw_dcb_iterations = bypass_raw_dcb_iterations->get_active(); + options.fastexport_bypass_raw_dcb_enhance = bypass_raw_dcb_enhance->get_active (); + options.fastexport_bypass_raw_lmmse_iterations = bypass_raw_lmmse_iterations->get_active(); + options.fastexport_bypass_raw_ca = bypass_raw_ca->get_active (); + options.fastexport_bypass_raw_linenoise = bypass_raw_linenoise->get_active (); + options.fastexport_bypass_raw_greenthresh = bypass_raw_greenthresh->get_active (); + options.fastexport_bypass_raw_df = bypass_raw_df->get_active (); + options.fastexport_bypass_raw_ff = bypass_raw_ff->get_active (); + + //saving demosaic_method + int currentRow = raw_dmethod->get_active_row_number(); + if( currentRow>=0 && currentRow < procparams::RAWParams::numMethods) + options.fastexport_raw_dmethod = procparams::RAWParams::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"; + if (resize_method->get_active_row_number() == 0) + options.fastexport_resize_method = "Nearest"; + else if (resize_method->get_active_row_number() == 1) + options.fastexport_resize_method = "Bilinear"; + else if (resize_method->get_active_row_number() == 2) + options.fastexport_resize_method = "Bicubic"; + else if (resize_method->get_active_row_number() == 3) + options.fastexport_resize_method = "Bicubic (Softer)"; + else if (resize_method->get_active_row_number() == 4) + options.fastexport_resize_method = "Bicubic (Sharper)"; + else if (resize_method->get_active_row_number() == 5) + 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_raw_all_enhance->set_active (options.fastexport_bypass_raw_all_enhance ); + bypass_raw_ccSteps->set_active (options.fastexport_bypass_raw_ccSteps ); + bypass_raw_dcb_iterations->set_active(options.fastexport_bypass_raw_dcb_iterations ); + bypass_raw_dcb_enhance->set_active (options.fastexport_bypass_raw_dcb_enhance ); + bypass_raw_lmmse_iterations->set_active(options.fastexport_bypass_raw_lmmse_iterations ); + bypass_raw_ca->set_active (options.fastexport_bypass_raw_ca ); + bypass_raw_linenoise->set_active (options.fastexport_bypass_raw_linenoise ); + bypass_raw_greenthresh->set_active (options.fastexport_bypass_raw_greenthresh ); + bypass_raw_df->set_active (options.fastexport_bypass_raw_df ); + bypass_raw_ff->set_active (options.fastexport_bypass_raw_ff ); + + //demosaic method + raw_dmethod->set_active(procparams::RAWParams::numMethods); + for( size_t i=0; i< procparams::RAWParams::numMethods;i++) + if( options.fastexport_raw_dmethod == procparams::RAWParams::methodstring[i]){ + raw_dmethod->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 ; + + resize_method->set_active (2); + if (options.fastexport_resize_method == "Nearest") + resize_method->set_active (0); + else if (options.fastexport_resize_method == "Bilinear") + resize_method->set_active (1); + else if (options.fastexport_resize_method == "Bicubic") + resize_method->set_active (2); + else if (options.fastexport_resize_method == "Bicubic (Softer)") + resize_method->set_active (3); + else if (options.fastexport_resize_method == "Bicubic (Sharper)") + resize_method->set_active (4); + else if (options.fastexport_resize_method == "Lanczos") + resize_method->set_active (5); + else if (options.fastexport_resize_method == "Downscale (Better)" || + options.fastexport_resize_method == "Downscale (Faster)") + { + resize_method->set_active (5); + } + + 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_raw_all_enhanceConn.block (true); + bypass_raw_ccStepsConn.block (true); + bypass_raw_dcb_iterationsConn.block (true); + bypass_raw_dcb_enhanceConn.block (true); + bypass_raw_lmmse_iterationsConn.block (true); + bypass_raw_caConn.block (true); + bypass_raw_linenoiseConn.block (true); + bypass_raw_greenthreshConn.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_raw_all_enhance->set_active(bypass_ALL->get_active()); + bypass_raw_ccSteps->set_active(bypass_ALL->get_active()); + bypass_raw_dcb_iterations->set_active(bypass_ALL->get_active()); + bypass_raw_dcb_enhance->set_active(bypass_ALL->get_active()); + bypass_raw_lmmse_iterations->set_active(bypass_ALL->get_active()); + bypass_raw_ca->set_active(bypass_ALL->get_active()); + bypass_raw_linenoise->set_active(bypass_ALL->get_active()); + bypass_raw_greenthresh->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_raw_all_enhanceConn.block (false); + bypass_raw_ccStepsConn.block (false); + bypass_raw_dcb_iterationsConn.block (false); + bypass_raw_dcb_enhanceConn.block (false); + bypass_raw_lmmse_iterationsConn.block (false); + bypass_raw_caConn.block (false); + bypass_raw_linenoiseConn.block (false); + bypass_raw_greenthreshConn.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_bypass_raw_all_enhance +fastexport_bypass_raw_ccSteps +fastexport_bypass_raw_dcb_iterations +fastexport_bypass_raw_dcb_enhance +fastexport_bypass_raw_ca +fastexport_bypass_raw_linenoise +fastexport_bypass_raw_greenthresh +fastexport_bypass_raw_df +fastexport_bypass_raw_ff +fastexport_raw_dmethod +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..566fb76ae --- /dev/null +++ b/rtgui/exportpanel.h @@ -0,0 +1,116 @@ +/* + * 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_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_dmethod; + MyComboBoxText* resize_method; + + Gtk::CheckButton* bypass_raw_dcb_iterations; + Gtk::CheckButton* bypass_raw_dcb_enhance; + Gtk::CheckButton* bypass_raw_lmmse_iterations; + Gtk::CheckButton* bypass_raw_ccSteps; + Gtk::CheckButton* raw_all_enhance; + Gtk::CheckButton* bypass_raw_linenoise; + Gtk::CheckButton* bypass_raw_greenthresh; + + 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_raw_all_enhanceConn ; + sigc::connection bypass_raw_ccStepsConn ; + sigc::connection bypass_raw_dcb_iterationsConn; + sigc::connection bypass_raw_dcb_enhanceConn ; + sigc::connection bypass_raw_lmmse_iterationsConn; + sigc::connection bypass_raw_caConn ; + sigc::connection bypass_raw_linenoiseConn ; + sigc::connection bypass_raw_greenthreshConn ; + 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..1cf4424e9 --- /dev/null +++ b/rtgui/filebrowser.cc @@ -0,0 +1,1731 @@ +/* + * 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); + + signal_style_changed().connect( sigc::mem_fun(*this, &FileBrowser::styleChanged) ); + + 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 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); + 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 (); +} + +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) { + std::vector entries; + for (size_t i=0; ithumbnail); + tbl->openRequested (entries); + } + 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) && ctrl) { + copyProfile (); + return true; + } + else if ((event->keyval==GDK_V || event->keyval==GDK_v) && ctrl && !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_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 && inTabMode) + 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 && inTabMode) + 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 (); + 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())); + + // 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(",", filter.queryFileName.uppercase()); + for(int i=0; ithumbnail->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 (size_t k=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(); +} diff --git a/rtgui/filebrowser.h b/rtgui/filebrowser.h new file mode 100644 index 000000000..a939f38ed --- /dev/null +++ b/rtgui/filebrowser.h @@ -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 . + */ +#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 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) {} +}; + +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 (); + + 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 (); + + 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..772bba732 --- /dev/null +++ b/rtgui/filebrowserentry.cc @@ -0,0 +1,732 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 + +#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), 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 () { + // Only make a (slow) processed preview if the picture has been edited at all + if ( thumbnail && + thumbnail->isQuick() && (!options.internalThumbIfUntouched || thumbnail->isPParamsValid()) ) + { + thumbImageUpdater->add(this, &updatepriority, true, 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 (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); + 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); + } +} + +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; + g_idle_add_full (G_PRIORITY_LOW, updateImageUI, param, NULL); +} + +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; + + 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..4f5a559e5 --- /dev/null +++ b/rtgui/filebrowserentry.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 _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; + 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..b0e4b1045 --- /dev/null +++ b/rtgui/filecatalog.cc @@ -0,0 +1,1979 @@ +/* + * 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); + buttonBar->pack_start (*bTrash, 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 + + 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; + + 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() +{ + 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)); + 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; + + 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=fileBrowser->getNumFiltered(); + + 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::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() + buttonBar->get_height(); + if (!options.FileBrowserToolbarSingleRow) { + newHeight += hbToolBar1->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++) { + if (editedFiles.find (tmb[i]->getFileName())==editedFiles.end()){ + // 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_raw_all_enhance ) params.raw.all_enhance = false; + if (options.fastexport_bypass_raw_ccSteps ) params.raw.ccSteps = 0; + if (options.fastexport_bypass_raw_dcb_iterations ) params.raw.dcb_iterations = 0; + if (options.fastexport_bypass_raw_dcb_enhance ) params.raw.dcb_enhance = false; + if (options.fastexport_bypass_raw_lmmse_iterations ) params.raw.lmmse_iterations = 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_linenoise ) params.raw.linenoise = 0; + if (options.fastexport_bypass_raw_greenthresh ) params.raw.greenthresh = 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.dmethod = options.fastexport_raw_dmethod ; + 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); + 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; + + for (int i=0; i<18; i++) + bCateg[i].block (true); + + // button already toggled when entering this function from a mouse click, so + // we switch it back to its initial state. + if (isMouseClick) + b->set_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; i<18; i++) { + if (categoryButtons[i]->get_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 the only star still active + 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; i<18; i++) + categoryButtons[i]->set_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 + } + } + + 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; i<18; i++) + bCateg[i].block (false); +} + +BrowserFilter FileCatalog::getFilter () { + + BrowserFilter filter; + + bool anyRankFilterActive = bUnRanked->get_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(); + /* + * filter is setup in 2 steps + * Step 1: handle individual filters + */ + filter.showRanked[0] = bFilterClear->get_active() || bUnRanked->get_active () || bTrash->get_active () || + anyCLabelFilterActive || anyEditedFilterActive || anyRecentlySavedFilterActive; + + filter.showCLabeled[0] = bFilterClear->get_active() || bUnCLabeled->get_active () || bTrash->get_active () || + anyRankFilterActive || anyEditedFilterActive || anyRecentlySavedFilterActive; + + for (int i=1; i<=5; i++){ + filter.showRanked[i] = bFilterClear->get_active() || bRank[i-1]->get_active () || bTrash->get_active () || + anyCLabelFilterActive || anyEditedFilterActive || anyRecentlySavedFilterActive; + + filter.showCLabeled[i] = bFilterClear->get_active() || bCLabel[i-1]->get_active () || bTrash->get_active () || + anyRankFilterActive || anyEditedFilterActive || anyRecentlySavedFilterActive; + } + + for (int i=0; i<2; i++){ + filter.showEdited[i] = bFilterClear->get_active() || bEdited[i]->get_active () || bTrash->get_active () || + anyRankFilterActive || anyCLabelFilterActive || anyRecentlySavedFilterActive; + + filter.showRecentlySaved[i] = bFilterClear->get_active() || bRecentlySaved[i]->get_active () || bTrash->get_active () || + 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)){ + + 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 = bFilterClear->get_active() || bTrash->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::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); + } + else { + tbLeftPanel_1->set_image (*iLeftPanel_1_Show); + } +} + +void FileCatalog::tbRightPanel_1_toggled () { + if (tbRightPanel_1->get_active()){ + filepanel->rightBox->show(); + tbRightPanel_1->set_image (*iRightPanel_1_Hide); + } + else{ + filepanel->rightBox->hide(); + tbRightPanel_1->set_image (*iRightPanel_1_Show); + } +} + +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::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; + case GDK_t: + case GDK_T: + categoryButtonToggled(bTrash,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; + } + } + + if (fileBrowser->keyPressed(event)) + return true; + + return false; +} diff --git a/rtgui/filecatalog.h b/rtgui/filecatalog.h new file mode 100644 index 000000000..37dfdfaf6 --- /dev/null +++ b/rtgui/filecatalog.h @@ -0,0 +1,259 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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* categoryButtons[18]; + Gtk::ToggleButton* exifInfo; + sigc::connection bCateg[18]; + 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 *iRightArrow_red, *iRightArrow; + 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 (); + + // 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 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 CheckSidePanelsVisibility(); + void toggleSidePanels(); + +#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..55851941e --- /dev/null +++ b/rtgui/filepanel.cc @@ -0,0 +1,289 @@ + +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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" + +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 () ); + //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); + + 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* 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 (*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 (); +} + +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); +} + +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()); + } + } + } +} + +bool FilePanel::fileSelected (Thumbnail* thm) { + + if (!parent) + return false; + + // Check if it's already open BEFORE loading the file + if (options.tabbedUI && parent->selectEditorPanel(Glib::path_get_basename (thm->getFileName()))) + return true; + + // try to open the file + bool loading = thm->imageLoad( true ); + if( !loading ) return false; + + 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 ){ + + if (pc->returnValue() && thm) { + + 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,Glib::path_get_basename (thm->getFileName())); + } + epanel->open(thm, pc->returnValue() ); + } else { + { + GThreadLock lock; // Acquiring the GUI... not sure that it's necessary, but it shouldn't harm + parent->SetEditorCurrent(); + } + parent->epanel->open(thm, pc->returnValue() ); + } + } 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 pc; + + { + GThreadLock lock; // Acquiring the GUI... not sure that it's necessary, but it shouldn't harm + parent->setProgress(0.); + parent->setProgressStr(""); + } + 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; + bool shift = event->state & GDK_SHIFT_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 100644 index 000000000..18d1ac59c --- /dev/null +++ b/rtgui/filepanel.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 _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 + + Gtk::VPaned* tpcPaned; + BatchToolPanelCoordinator* tpc; + History* history; + //FilterPanel* filterPanel; + RTWindow* parent; + Gtk::Notebook* rightNotebook; + + int error; + public: + 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 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 closeing rt: it saves file browser relating 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/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..a453b7bdb --- /dev/null +++ b/rtgui/flatcurveeditorsubgroup.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 "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 "curveeditor.h" +#include "flatcurveeditorsubgroup.h" + +FlatCurveEditorSubGroup::FlatCurveEditorSubGroup (CurveEditorGroup* prt, Glib::ustring& curveDir) : CurveEditorSubGroup(curveDir) { + + valLinear = (int)FCT_Linear; + valUnchanged = (int)FCT_Unchanged; + parent = prt; + + // ControlPoints curve + CPointsCurveBox = new Gtk::VBox (); + CPointsCurveBox->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); + CPointsCurveBox->pack_start (*CPointsCurve, Gtk::PACK_EXPAND_WIDGET, 0); + + Gtk::HBox* 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"))); + + 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); + + CPointsCurveBox->pack_end (*CPointsbbox, Gtk::PACK_SHRINK, 0); + CPointsCurveBox->show_all (); + + 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) ); + + 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; +} + +/* + * 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 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(); + 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; +} + +/* + * 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(int cType, double iValue) { + switch ((FlatCurveType) cType) { + case (FCT_MinMaxCPoints) : // = Control cage + CPointsCurve->reset (iValue); + 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..95eb90b4b --- /dev/null +++ b/rtgui/flatcurveeditorsubgroup.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 _FLATCURVEEDITORSUBGROUP_ +#define _FLATCURVEEDITORSUBGROUP_ + +#include +#include "curveeditorgroup.h" + +class FlatCurveEditor; + +class FlatCurveEditorSubGroup: public CurveEditorSubGroup { + + friend class FlatCurveEditor; + +protected: + Gtk::VBox* CPointsCurveBox; + + MyFlatCurve* CPointsCurve; + + Gtk::Button* saveCPoints; + Gtk::Button* loadCPoints; + Gtk::Button* copyCPoints; + Gtk::Button* pasteCPoints; + +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); + +protected: + void storeCurveValues (CurveEditor* ce, const std::vector& p); + void storeDisplayedCurve (); + void restoreDisplayedHistogram (); + void savePressed (); + void loadPressed (); + void copyPressed (); + void pastePressed (); + bool curveReset (int cType, double iValue); + void removeEditor (); + const std::vector getCurveFromGUI (int type); +}; + +#endif diff --git a/rtgui/flatfield.cc b/rtgui/flatfield.cc new file mode 100755 index 000000000..a3723c0e1 --- /dev/null +++ b/rtgui/flatfield.cc @@ -0,0 +1,253 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 () : Gtk::VBox(), FoldableToolPanel(this) +{ + set_border_width(4); + + hbff = Gtk::manage(new Gtk::HBox()); + 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, 4); + hbff->pack_start(*flatFieldFile); + hbff->pack_start(*flatFieldFileReset, Gtk::PACK_SHRINK, 4); + 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") +": "))); + 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); + + pack_start( *hbff, Gtk::PACK_SHRINK, 4); + pack_start( *flatFieldAutoSelect, Gtk::PACK_SHRINK, 4); + pack_start( *ffInfo, Gtk::PACK_SHRINK, 4); + pack_start( *hbffbt, Gtk::PACK_SHRINK, 4); + pack_start( *flatFieldBlurRadius, Gtk::PACK_SHRINK, 4); + + 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 = ""; +} + +void FlatField::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited) +{ + disableListener (); + flatFieldAutoSelectconn.block (true); + flatFieldBlurTypeconn.block (true); + + if(pedited ){ + flatFieldAutoSelect->set_inconsistent (!pedited->raw.ff_AutoSelect); + flatFieldBlurRadius->setEditedState( pedited->raw.ff_BlurRadius ? Edited : UnEdited ); + 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); + hbff->set_sensitive( !pp->raw.ff_AutoSelect ); + + lastFFAutoSelect = pp->raw.ff_AutoSelect; + 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(""); + + flatFieldAutoSelect ->set_active(pp->raw.ff_AutoSelect); + flatFieldBlurRadius->setValue (pp->raw.ff_BlurRadius); + flatFieldBlurType->set_active(procparams::RAWParams::numFlatFileBlurTypes); + + //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; + } + + flatFieldAutoSelect->set_active (pp->raw.ff_AutoSelect); + flatFieldBlurRadius->setValue (pp->raw.ff_BlurRadius); + + ffChanged = false; + + flatFieldAutoSelectconn.block (false); + flatFieldBlurTypeconn.block (false); + enableListener (); +} + +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(); + + 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_BlurType = flatFieldBlurType->get_active_row_number() != procparams::RAWParams::numFlatFileBlurTypes; + } + +} + +void FlatField::adjusterChanged (Adjuster* a, double newval) +{ + if (listener) { + + Glib::ustring value = a->getTextValue(); + + listener->panelChanged (EvFlatFieldBlurRadius, value ); + } +} + +void FlatField::setBatchMode(bool batchMode) +{ + ToolPanel::setBatchMode (batchMode); + flatFieldBlurRadius->showEditedCB (); +} + +void FlatField::setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited) +{ + flatFieldBlurRadius->setDefault( defParams->raw.ff_BlurRadius); + + if (pedited) { + flatFieldBlurRadius->setDefaultEditedState( pedited->raw.ff_BlurRadius ? Edited : UnEdited); + } else { + flatFieldBlurRadius->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; + //flatFieldFile->set_current_name(""); + flatFieldFile->set_filename (""); + + 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 (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 (Gtk::FileChooserError &err) {} + } + lastShortcutPath = path; + try { + flatFieldFile->add_shortcut_folder(path); + } + catch (Gtk::FileChooserError &err) {} + } +} diff --git a/rtgui/flatfield.h b/rtgui/flatfield.h new file mode 100644 index 000000000..fb83bcc80 --- /dev/null +++ b/rtgui/flatfield.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 _FLATFIELD_H_ +#define _FLATFIELD_H_ + +#include +#include +#include "adjuster.h" +#include "toolpanel.h" +#include "../rtengine/rawimage.h" +#include "guiutils.h" + +class FFProvider { + public: + virtual rtengine::RawImage* getFF() = 0; + // add other info here +}; + +class FlatField : public Gtk::VBox, public AdjusterListener, public FoldableToolPanel { + +protected: + + MyFileChooserButton *flatFieldFile; + std::auto_ptr flatFieldFilePersister; + Gtk::Label *ffLabel; + Gtk::Label *ffInfo; + Gtk::Button *flatFieldFileReset; + Gtk::CheckButton* flatFieldAutoSelect; + Adjuster* flatFieldBlurRadius; + MyComboBoxText* flatFieldBlurType; + Gtk::HBox *hbff; + bool ffChanged; + bool lastFFAutoSelect; + FFProvider *ffp; + sigc::connection flatFieldFileconn, flatFieldAutoSelectconn, flatFieldBlurTypeconn; + Glib::ustring lastShortcutPath; + +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 setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + + void adjusterChanged (Adjuster* a, double 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..0eb43b5de --- /dev/null +++ b/rtgui/gradient.cc @@ -0,0 +1,180 @@ +/* + * This file is part of RawTherapee. + */ +#include "gradient.h" +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +Gradient::Gradient () : Gtk::VBox(), FoldableToolPanel(this) +{ + set_border_width(4); + + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); + enabled->set_active (false); + enaConn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &Gradient::enabledChanged) ); + + 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(*enabled); + pack_start(*Gtk::manage (new Gtk::HSeparator()), Gtk::PACK_EXPAND_WIDGET, 4); + pack_start (*strength); + pack_start (*degree); + pack_start (*feather); + pack_start (*centerX); + pack_start (*centerY); + + show_all(); +} + +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); + enabled->set_inconsistent (!pedited->gradient.enabled); + } + + enaConn.block (true); + enabled->set_active (pp->gradient.enabled); + enaConn.block (false); + 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); + + lastEnabled = pp->gradient.enabled; + + enableListener (); +} + +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 = enabled->get_active(); + + 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 = !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) { + + if (listener && enabled->get_active()) { + 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 (batchMode) { + if (enabled->get_inconsistent()) { + enabled->set_inconsistent (false); + enaConn.block (true); + enabled->set_active (false); + enaConn.block (false); + } + else if (lastEnabled) + enabled->set_inconsistent (true); + + lastEnabled = enabled->get_active (); + } + if (listener) { + if (enabled->get_active()) + 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) +{ + ToolPanel::setBatchMode (batchMode); + degree->showEditedCB (); + feather->showEditedCB (); + strength->showEditedCB (); + centerX->showEditedCB (); + centerY->showEditedCB (); +} diff --git a/rtgui/gradient.h b/rtgui/gradient.h new file mode 100644 index 000000000..7b46b773f --- /dev/null +++ b/rtgui/gradient.h @@ -0,0 +1,38 @@ +/* + * This file is part of RawTherapee. + */ +#ifndef _GRADIENT_H_ +#define _GRADIENT_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" + +class Gradient : public Gtk::VBox, public AdjusterListener, public FoldableToolPanel { + + protected: + Gtk::CheckButton* enabled; + Adjuster* degree; + Adjuster* feather; + Adjuster* strength; + Adjuster* centerX; + Adjuster* centerY; + bool lastEnabled; + sigc::connection enaConn; + + public: + + 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 adjusterChanged (Adjuster* a, double newval); + void enabledChanged (); + void setAdjusterBehavior (bool degreeadd, bool featheradd, bool strengthadd, bool centeradd); + void trimValues (rtengine::procparams::ProcParams* pp); +}; + +#endif diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc new file mode 100644 index 000000000..d32da9e7c --- /dev/null +++ b/rtgui/guiutils.cc @@ -0,0 +1,627 @@ +/* + * 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/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::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) { + + 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-1-startx)*scale; + double c2y = (cparams.y+cparams.h-1-starty)*scale; + + // crop overlay color, linked with crop windows background + if (options.bgcolor==0) + 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, c1y); + cr->rectangle (imx, imy+c2y, imw, imh-c2y); + cr->rectangle (imx, imy+c1y, c1x, c2y-c1y+1); + cr->rectangle (imx+c2x, imy+c1y, imw-c2x, c2y-c1y+1); + cr->fill (); + + // rectangle around the cropped area and guides + if (cparams.guide!="None") { + double rectx1 = c1x + imx + 0.5; + double recty1 = c1y + imy + 0.5; + double rectx2 = c2x + imx + 0.5; + double recty2 = c2y + imy + 0.5; + cr->set_line_width (1.0); + cr->set_source_rgb (1.0, 1.0, 1.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 (); + 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 (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") { + // 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 (cparams.guide=="Harmonic means 1") { + horiz_ratios.push_back (1.0-0.618); + vert_ratios.push_back (1.0-0.618); + } + else if (cparams.guide=="Harmonic means 2") { + horiz_ratios.push_back (0.618); + vert_ratios.push_back (1.0-0.618); + } + else if (cparams.guide=="Harmonic means 3") { + horiz_ratios.push_back (1.0-0.618); + vert_ratios.push_back (0.618); + } + else if (cparams.guide=="Harmonic means 4") { + horiz_ratios.push_back (0.618); + vert_ratios.push_back (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, shortSideNumLines; + if (w>longSideNumLines && h>longSideNumLines) { + if (w>h) { + for (int i=1;iset_source_rgb (1.0, 1.0, 1.0); + cr->move_to (rectx1, recty1 + (recty2-recty1) * horiz_ratios[i]); + cr->line_to (rectx2, recty1 + (recty2-recty1) * horiz_ratios[i]); + 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 (rectx1, recty1 + (recty2-recty1) * horiz_ratios[i]); + cr->line_to (rectx2, recty1 + (recty2-recty1) * horiz_ratios[i]); + cr->stroke (); + ds.resize (0); + cr->set_dash (ds, 0); + } + // Verticals + for (size_t i=0; iset_source_rgb (1.0, 1.0, 1.0); + cr->move_to (rectx1 + (rectx2-rectx1) * vert_ratios[i], recty1); + cr->line_to (rectx1 + (rectx2-rectx1) * vert_ratios[i], recty2); + 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 (rectx1 + (rectx2-rectx1) * vert_ratios[i], recty1); + cr->line_to (rectx1 + (rectx2-rectx1) * vert_ratios[i], recty2); + cr->stroke (); + ds.resize (0); + cr->set_dash (ds, 0); + } + } + else { + int corners_from[4][2]; + int corners_to[4][2]; + int mindim = min(rectx2-rectx1+1, recty2-recty1+1); + 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_rgb (1.0, 1.0, 1.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 (); + 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 (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); + } + } + } + cr->reset_clip (); +} + + +/* + * + * 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; + double step, page; + int maxAbs; + unsigned int digits, digits2; + unsigned int maxLen; + + get_range(vMin, vMax); + get_increments (step, page); + + 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) { + bool rcode = Gtk::Widget::on_key_press_event(event); + if ( (event->string[0] >= 'a' && event->string[0] <= 'z') + ||(event->string[0] >= 'A' && event->string[0] <= 'Z') + || event->string[0] == '+' + ) + return false; + return rcode; +} + +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; +} + +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 = y = w = h = 0; + dirty = true; +} + +bool BackBuffer::setDrawRectangle(Glib::RefPtr window, int newX, int newY, int newW, int 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 (newSize && window) { + // allocate a new Surface + if (newW>0 && newH>0) { + surface = window->create_similar_surface(Cairo::CONTENT_COLOR, w, h); + } + else { + // at least one dimension is null, so we delete the Surface + surface.clear(); + // and we reset all dimensions + x = y = w = h = 0; + } + 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(); + + // now copy the off-screen Surface to the destination Surface + Cairo::RefPtr crDest = Cairo::Context::create(destSurface); + crDest->set_source(surface, x, y); + 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) { + // now copy the off-screen Surface to the destination Surface + Cairo::RefPtr crDest = Cairo::Context::create(destBackBuffer->getSurface()); + crDest->set_source(surface, x, y); + 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) { + // now copy the off-screen Surface to the destination Surface + Cairo::RefPtr crDest = Cairo::Context::create(destSurface); + crDest->set_source(surface, x, y); + 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..6ffdc601f --- /dev/null +++ b/rtgui/guiutils.h @@ -0,0 +1,289 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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); + +/** + * @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 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); +}; + +/** + * @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 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 + 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 + bool setDrawRectangle(Glib::RefPtr window, int newX, int newY, int newW, int newH); + + 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 deleteSurface() { 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 w; } + int getHeight() { return h; } +}; + + +#endif diff --git a/rtgui/histogrampanel.cc b/rtgui/histogrampanel.cc new file mode 100644 index 000000000..54e568328 --- /dev/null +++ b/rtgui/histogrampanel.cc @@ -0,0 +1,835 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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" + +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, 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); + 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; + + signal_style_changed().connect( sigc::mem_fun(*this, &HistogramRGBArea::styleChanged) ); +} + +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) { + + 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) { + // Luma + cr->set_source_rgb(1.0, 1.0, 1.0); + cr->move_to((int)((r+g+b)/3*(winw/256.0)), 0); + cr->line_to((int)((r+g+b)/3*(winw/256.0)), winh-0); + cr->stroke(); + } + if (needChroma) { + // Luma + cr->set_source_rgb(1.0, 1.0, 1.0); + cr->move_to((int)((r+g+b)/3*(winw/256.0)), 0); + cr->line_to((int)((r+g+b)/3*(winw/256.0)), winh-0); + cr->stroke(); + } + + } +} + +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::styleChanged (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), 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; + + signal_style_changed().connect( sigc::mem_fun(*this, &HistogramArea::styleChanged) ); +} + +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; + + // 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 && lhist[i]>fullhistheight) + fullhistheight = lhist[i]; + if (needChroma && chist[i]>fullhistheight) + fullhistheight = chist[i]; + if (needRed && (rawMode?rhistRaw:rhist)[i]>fullhistheight) + fullhistheight = rh[i]; + if (needGreen && (rawMode?ghistRaw:ghist)[i]>fullhistheight) + fullhistheight = gh[i]; + if (needBlue && (rawMode?bhistRaw:bhist)[i]>fullhistheight) + fullhistheight = bh[i]; + } + + int realhistheight = fullhistheight; + + if (!fullMode) { + int area = 0; + for (int i=0; ii) || (needChroma && !rawMode && chist[j]>i) || (needRed && rh[j]>i) || (needGreen && gh[j]>i) || (needBlue && bh[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, lhist, realhistheight, winw, ui, oi); + } + + + if (needRed) { + drawCurve(cr, rh, realhistheight, winw, winh); + cr->set_source_rgb (1.0, 0.0, 0.0); + cr->stroke (); + + drawMarks(cr, rh, realhistheight, winw, ui, oi); + } + if (needGreen) { + drawCurve(cr, gh, realhistheight, winw, winh); + cr->set_source_rgb (0.0, 1.0, 0.0); + cr->stroke (); + + drawMarks(cr, gh, realhistheight, winw, ui, oi); + } + if (needBlue) { + drawCurve(cr, bh, realhistheight, winw, winh); + cr->set_source_rgb (0.0, 0.0, 1.0); + cr->stroke (); + + drawMarks(cr, bh, 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::styleChanged (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..6e32a52ac --- /dev/null +++ b/rtgui/histogrampanel.h @@ -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 . + */ +#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 { + + 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); + 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 styleChanged (const Glib::RefPtr& style); + private: + // 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 styleChanged (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, 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..87f422139 --- /dev/null +++ b/rtgui/history.cc @@ -0,0 +1,342 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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; + pe.set(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; + pe.set(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..5af1fae39 --- /dev/null +++ b/rtgui/hsvequalizer.cc @@ -0,0 +1,247 @@ +/* + * 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 () : Gtk::VBox(), FoldableToolPanel(this) { + + set_border_width(4); + + 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->setBottomBarBgGradient(bottomMilestones); + //hshape->setLeftBarColorProvider(this); Not working yet + hshape->setCurveColorProvider(this, 1); + + sshape = static_cast(curveEditorG->addCurve(CT_Flat, M("TP_HSVEQUALIZER_SAT"))); + 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->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::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 (); + } +} + +/* +void HSVEqualizer::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + for (int i = 0; i < 8; i++) { + sat[i]->setDefault(defParams->hsvequalizer.sat[i]); + val[i]->setDefault(defParams->hsvequalizer.val[i]); + hue[i]->setDefault(defParams->hsvequalizer.hue[i]); + } + + if (pedited) { + for (int i = 0; i < 8; i++) { + sat[i]->setDefaultEditedState(pedited->hsvequalizer.sat[i] ? Edited : UnEdited); + val[i]->setDefaultEditedState(pedited->hsvequalizer.val[i] ? Edited : UnEdited); + hue[i]->setDefaultEditedState(pedited->hsvequalizer.hue[i] ? Edited : UnEdited); + } + } + else { + for (int i = 0; i < 8; i++) { + sat[i]->setDefaultEditedState(Irrelevant); + val[i]->setDefaultEditedState(Irrelevant); + hue[i]->setDefaultEditedState(Irrelevant); + } + } +} +*/ + +/* + * 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::adjusterChanged (Adjuster* a, double newval) { + + if (listener && enabled->get_active()) { + std::stringstream ss; + ss << "("; + int i; + if (hsvchannel->get_active_row_number()==0) { + for (i = 0; i < 8; i++) { + if (i > 0) { + ss << ", "; + } + if (i == 4) { + ss << "\n"; + } + ss << static_cast(sat[i]->getValue()); + } + ss << ")"; + listener->panelChanged (EvHSVEqualizerS, ss.str()); + } + else if (hsvchannel->get_active_row_number()==1) { + for (i = 0; i < 8; i++) { + if (i > 0) { + ss << ", "; + } + if (i == 4) { + ss << "\n"; + } + ss << static_cast(val[i]->getValue()); + } + ss << ")"; + listener->panelChanged (EvHSVEqualizerV, ss.str()); + } + else if (hsvchannel->get_active_row_number()==2) { + for (i = 0; i < 8; i++) { + if (i > 0) { + ss << ", "; + } + if (i == 4) { + ss << "\n"; + } + ss << static_cast(hue[i]->getValue()); + } + ss << ")"; + listener->panelChanged (EvHSVEqualizerH, ss.str()); + } + + //listener->panelChanged (EvHSVEqualizer, ss.str()); + } +} +*/ + +void HSVEqualizer::colorForValue (double valX, double valY, int callerId, ColorCaller* caller) { + + float r, g, b; + + 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..0067672b7 --- /dev/null +++ b/rtgui/hsvequalizer.h @@ -0,0 +1,60 @@ +/* + * 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 Gtk::VBox, public AdjusterListener, public FoldableToolPanel, public CurveListener, public ColorProvider +{ + +protected: + + Gtk::CheckButton * enabled; + + 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 autoOpenCurve (); + virtual void colorForValue (double valX, double valY, 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..ae33732e9 --- /dev/null +++ b/rtgui/icmpanel.cc @@ -0,0 +1,730 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 () : Gtk::VBox(), FoldableToolPanel(this), iunchanged(NULL), icmplistener(NULL), lastRefFilename("") { + + set_border_width(4); + isBatchMode = lastToneCurve = 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); + + ckbToneCurve = Gtk::manage (new Gtk::CheckButton (M("TP_ICM_TONECURVE"))); + ckbToneCurve->set_sensitive (false); + ckbToneCurve->set_tooltip_text (M("TP_ICM_TONECURVE_TOOLTIP")); + iVBox->pack_start (*ckbToneCurve, 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_border_width(4); + 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("TP_ICM_FILEDLGFILTERICM")); + filter_icc.add_pattern("*.dcp"); + filter_icc.add_pattern("*.DCP"); + filter_icc.add_pattern("*.dng"); + filter_icc.add_pattern("*.DNG"); + filter_icc.add_pattern("*.icc"); + filter_icc.add_pattern("*.icm"); + filter_icc.add_pattern("*.ICC"); + filter_icc.add_pattern("*.ICM"); + Gtk::FileFilter filter_any; + filter_any.set_name(M("TP_ICM_FILEDLGFILTERANY")); + filter_any.add_pattern("*"); + + ipDialog->add_filter (filter_icc); + 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)); + 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); + 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); + 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); + } else { + ckbToneCurve->set_active (false); + } + 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) { + 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); + } else { + if (dcpIll->get_active_row_number() != -1) { + dcpIll->set_active(-1); + } + } + } + } + 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); + blendcmsconn.block(true); + + if (pp->icm.input == "(none)" && icamera->get_state()!=Gtk::STATE_INSENSITIVE) { + 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)") && 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 == "(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; + + 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); + 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); + 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(); + pp->icm.toneCurve = ckbToneCurve->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.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::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::FileFilter filter_tif; + filter_tif.set_name(M("SAVEDLG_TIFFFILTER")); + filter_tif.add_pattern("*.tif"); + filter_tif.add_pattern("*.tiff"); + dialog.add_filter(filter_tif); + + Gtk::FileFilter filter_any; + filter_any.set_name(M("TP_ICM_FILEDLGFILTERANY")); + filter_any.add_pattern("*"); + dialog.add_filter(filter_any); + + //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); + 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..32ed030ae --- /dev/null +++ b/rtgui/icmpanel.h @@ -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 . + */ +#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) {} +}; + +class ICMPanel : public Gtk::VBox, public AdjusterListener, public FoldableToolPanel { + + protected: + Adjuster* gampos; + Adjuster* slpos; + bool lastgamfree; + sigc::connection gamcsconn; + //bool freegamma; + bool lastToneCurve; + sigc::connection tcurveconn; + 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* 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 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..b393e22b6 --- /dev/null +++ b/rtgui/ilabel.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 "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); + + signal_style_changed().connect( sigc::mem_fun(*this, &ILabel::styleChanged) ); +} + +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::styleChanged (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..48f0bf20f --- /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 styleChanged (const Glib::RefPtr& style); +}; + +#endif + diff --git a/rtgui/imagearea.cc b/rtgui/imagearea.cc new file mode 100644 index 000000000..3e0e5a229 --- /dev/null +++ b/rtgui/imagearea.cc @@ -0,0 +1,482 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 +#include "cropwindow.h" +#include "../rtengine/refreshmap.h" +#include "options.h" + +ImageArea::ImageArea (ImageAreaPanel* p) : parent(p) { + + infotext = ""; + cropgl = NULL; + pmlistener = NULL; + pmhlistener = NULL; + focusGrabber = NULL; + mainCropWindow = NULL; + previewHandler = NULL; + lastClosedX = -1; + showClippedH = false; + showClippedS = false; + listener = NULL; + + zoomPanel = Gtk::manage (new ZoomPanel (this)); + indClippedPanel = Gtk::manage (new IndicateClippedPanel (this)); + previewModePanel = Gtk::manage (new PreviewModePanel (this)); + + signal_style_changed().connect( sigc::mem_fun(*this, &ImageArea::styleChanged) ); + 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); + 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 + } + 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(); + if( i!=cropWins.end() ){ + (*i)->getPosition (lastClosedX, lastClosedY); + (*i)->getSize (lastClosedW, lastClosedH); + } + for( ;i!=cropWins.end();i++ ){ + delete *i; + } + cropWins.clear(); + + mainCropWindow->setObservedCropWin (NULL); + } + ipc = ipc_; + +} + +void ImageArea::setPreviewHandler (PreviewHandler* ph) { + + previewHandler = ph; +} + +void ImageArea::styleChanged (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) + 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->x, event->y); + else { + CropWindow* cw = getCropWindow (event->x, event->y); + if (cw) + cw->pointerMoved (event->x, event->y); + } + 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; +} + + +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); + cw->zoom11(); + cw->setCropGUIListener (cropgl); + cw->setPointerMotionListener (pmlistener); + cw->setPointerMotionHListener (pmhlistener); + cropWins.push_front (cw); + + // Position the new crop window in a checkerboard, or used the last position + if (lastClosedX<0) { + int K = 2; + int hBorder = get_width()/K/8; + int vBorder = get_height()/K/8; + int N = cropWins.size()-1; + int layer = N/K/K; + int row = K-1 - (N % (K*K)) / K; + int col = K-1 - (N % (K*K)) % K; + int cropwidth, cropheight; + + cropwidth = get_width()/K - hBorder; + cropheight = get_height()/K - vBorder; + + if (options.squareDetailWindow){ + // force square CropWindow (this is faster as area is smaller) + if (cropwidthsetSize (cropwidth,cropheight); + cw->setPosition (col*get_width()/K + hBorder/2 + layer*30, row*get_height()/K + vBorder/2 + layer*30); + } + else { + cw->setPosition (lastClosedX, lastClosedY); + cw->setSize(lastClosedW, lastClosedH); + } + 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()); + + ipc->startProcessing(M_HIGHQUAL); + +// queue_draw (); +} + + +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; + cw->getPosition (lastClosedX, lastClosedY); + cw->getSize (lastClosedW, lastClosedH); + std::list::iterator i = std::find (cropWins.begin(), cropWins.end(), cw); + if (i!=cropWins.end()) + cropWins.erase (i); + delete cw; + 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) + mainCropWindow->zoomFit (); +} + +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..97b630e63 --- /dev/null +++ b/rtgui/imagearea.h @@ -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 . + */ +#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" + +class ImageAreaPanel; +class ImageArea : public Gtk::DrawingArea, public CropWindowListener { + + 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; + + int lastClosedX, lastClosedY, lastClosedW, lastClosedH; + + bool dirty; + CropWindow* focusGrabber; + CropGUIListener* cropgl; + PointerMotionListener* pmlistener; + PointerMotionListener* pmhlistener; + ImageAreaToolListener* listener; + + CropWindow* getCropWindow (int x, int y); + + public: + CropWindow* mainCropWindow; + 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); + void on_resized (Gtk::Allocation& req); + void styleChanged (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); + + // 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..379945581 --- /dev/null +++ b/rtgui/impulsedenoise.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 "impulsedenoise.h" +#include +#include +#include "guiutils.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +ImpulseDenoise::ImpulseDenoise () : Gtk::VBox(), FoldableToolPanel(this) { + + set_border_width(4); + + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); + enabled->set_active (false); + + thresh = Gtk::manage (new Adjuster (M("TP_IMPULSEDENOISE_THRESH"), 0, 100, 1, 50)); + + pack_start (*enabled); + pack_start (*Gtk::manage (new Gtk::HSeparator())); + pack_start (*thresh); + + enaConn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &ImpulseDenoise::enabledChanged) ); + 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); + enabled->set_inconsistent (!pedited->impulseDenoise.enabled); + } + + enaConn.block (true); + enabled->set_active (pp->impulseDenoise.enabled); + enaConn.block (false); + + lastEnabled = pp->impulseDenoise.enabled; + + thresh->setValue (pp->impulseDenoise.thresh); + + enableListener (); +} + +void ImpulseDenoise::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->impulseDenoise.thresh = thresh->getValue (); + pp->impulseDenoise.enabled = enabled->get_active(); + + if (pedited) { + pedited->impulseDenoise.thresh = thresh->getEditedState (); + pedited->impulseDenoise.enabled = !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 && enabled->get_active()) { + + listener->panelChanged (EvIDNThresh, Glib::ustring::format (std::setw(2), std::fixed, std::setprecision(1), a->getValue())); + } +} + +void ImpulseDenoise::enabledChanged () { + + if (batchMode) { + if (enabled->get_inconsistent()) { + enabled->set_inconsistent (false); + enaConn.block (true); + enabled->set_active (false); + enaConn.block (false); + } + else if (lastEnabled) + enabled->set_inconsistent (true); + + lastEnabled = enabled->get_active (); + } + + if (listener) { + if (enabled->get_active ()) + 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..350c759d0 --- /dev/null +++ b/rtgui/impulsedenoise.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 _IMPULSEDENOISE_H_ +#define _IMPULSEDENOISE_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" + +class ImpulseDenoise : public Gtk::VBox, public AdjusterListener, public FoldableToolPanel { + + protected: + Adjuster* thresh; + //Adjuster* edge; + Gtk::CheckButton* enabled; + bool lastEnabled; + sigc::connection enaConn; + + 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/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..3fd6e2f51 --- /dev/null +++ b/rtgui/labcurve.cc @@ -0,0 +1,549 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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" + +using namespace rtengine; +using namespace rtengine::procparams; + +LCurve::LCurve () : Gtk::VBox(), FoldableToolPanel(this) { + + set_border_width(4); + + 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")); + + ashape = static_cast(curveEditorG->addCurve(CT_Diagonal, "a")); + 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") + ); + //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); + + + chshape = static_cast(curveEditorG->addCurve(CT_Flat, M("TP_LABCURVE_CURVEEDITOR_CH"))); + chshape->setTooltip(M("TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP")); + chshape->setCurveColorProvider(this, 1); + + + hhshape = static_cast(curveEditorG->addCurve(CT_Flat, M("TP_LABCURVE_CURVEEDITOR_HH"))); + hhshape->setTooltip(M("TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP")); + hhshape->setCurveColorProvider(this, 5); + + 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->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")); + // 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->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::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, int callerId, ColorCaller *caller) { + + float R, G, B; + 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..fa24f4eec --- /dev/null +++ b/rtgui/labcurve.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 _LABCURVE_H_ +#define _LABCURVE_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" +#include "curveeditor.h" +#include "curveeditorgroup.h" +#include "colorprovider.h" + +class LCurve : public Gtk::VBox, 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 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, int callerId, ColorCaller* caller); +}; + +#endif diff --git a/rtgui/lensgeom.cc b/rtgui/lensgeom.cc new file mode 100644 index 000000000..e5a0b6304 --- /dev/null +++ b/rtgui/lensgeom.cc @@ -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 . + */ +#include "lensgeom.h" +#include "guiutils.h" +#include "rtimage.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +LensGeometry::LensGeometry () : Gtk::VBox(), FoldableToolPanel(this), rlistener(NULL) { + + set_border_width(4); + + 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 Gtk::VBox ()); + 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..0be5a8968 --- /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 Gtk::VBox, public FoldableToolPanel { + + protected: + Gtk::Button* autoCrop; + LensGeomListener* rlistener; + Gtk::CheckButton* fill; + bool lastFill; + sigc::connection fillConn; + Gtk::VBox* 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..7b085278e --- /dev/null +++ b/rtgui/lensprofile.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 "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 () : Gtk::VBox(), FoldableToolPanel(this) +{ + set_border_width(4); + + 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("TP_LENSPROFILE_FILEDLGFILTERLCP")); + 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); + updateDisabled(false); + } + + ckbUseDist->set_active (pp->lensProf.useDist); + ckbUseVign->set_active (pp->lensProf.useVign); + ckbUseCA->set_active (pp->lensProf.useCA); + + 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(); + } +} + +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); + ckbUseCA->set_sensitive(enable && allowFocusDep); +} diff --git a/rtgui/lensprofile.h b/rtgui/lensprofile.h new file mode 100644 index 000000000..e25555a24 --- /dev/null +++ b/rtgui/lensprofile.h @@ -0,0 +1,55 @@ +/* +* 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 Gtk::VBox, 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; + +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..f0daad6ac --- /dev/null +++ b/rtgui/main.cc @@ -0,0 +1,629 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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! + +#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,""); + + // 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(); + + Options::load (); + extProgStore->init(); + SoundManager::init(); + +#ifdef WIN32 + bool consoleOpened = false; + + if (argc>1 || options.rtSettings.verbose){ + 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)) { + AllocConsole(); + AttachConsole( GetCurrentProcessId() ) ; + // Don't allow CTRL-C in console to terminate RT + SetConsoleCtrlHandler( NULL, true ); + // Set title of console + char consoletitle[128]; + sprintf(consoletitle, "RawTherapee %s Console",VERSION); + SetConsoleTitle(consoletitle); + // increase size of screen buffer + COORD c; + c.X = 200; + c.Y = 1000; + SetConsoleScreenBufferSize( GetStdHandle( STD_OUTPUT_HANDLE ), c ); + // Disable console-Cursor + CONSOLE_CURSOR_INFO cursorInfo; + cursorInfo.dwSize = 100; + cursorInfo.bVisible = false; + SetConsoleCursorInfo( GetStdHandle( STD_OUTPUT_HANDLE ), &cursorInfo ); + if(!stdoutRedirectedtoFile) + freopen( "CON", "w", stdout ) ; + if(!stderrRedirectedtoFile) + freopen( "CON", "w", stderr ) ; + freopen( "CON", "r", stdin ) ; + + consoleOpened = true; + + // 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; + } + int ret = processLineParams( argc, argv); + if( ret <= 0 ) { + if(consoleOpened) { + printf("Press any key to exit RawTherapee\n"); + FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE)); + getch(); + } + return ret; + } + } +#else + if (argc>1 || 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); + +#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 isDirectory=false; + bool outputDirectory=false; + bool overwriteFiles=false; + bool sideProcParams=false; + bool copyParamsFile=false; + bool skipIfNoSidecar=false; + bool useDefault=false; + unsigned int sideCarFilePos = 0; + int compression=100; + 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': + outputType = "jpg"; + sscanf(&argv[iArg][2],"%d",&compression); + break; + case 't': + outputType = "tif"; + compression = ((argv[iArg][2]!='1')?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; + case 'h': + case '?': + default: + { + Glib::ustring pparamsExt = paramFileExtension.substr(1); + 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; + 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]|-t|-t1|-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 Image Processing Parameters" << std::endl; + std::cout << " -j[1-100] Specify output to be JPEG (on by default). Optionally add" << std::endl; + std::cout << " compression 1-100." << std::endl; + std::cout << " -t Specify output to be uncompressed 16-bit TIFF." << std::endl; + std::cout << " -t1 Specify output to be compressed 16-bit TIFF (ZIP compression)." << std::endl; + std::cout << " -n Specify output to be compressed 16-bit PNG." << std::endl; + std::cout << " -Y Overwrite output if present." << std::endl<load(Glib::build_filename(profPath, options.defProfRaw + paramFileExtension))) { + std::cerr << "Error: default Raw procparams file 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(Glib::build_filename(profPath, options.defProfImg + paramFileExtension))) { + std::cerr << "Error: default Image procparams file not found" << std::endl; + imgParams->deleteInstance(); + delete imgParams; + rawParams->deleteInstance(); + delete rawParams; + deleteProcParams(processingParams); + return -3; + } + } + + ParamsEdited paramsEdited; + 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 + ii = rtengine::InitialImage::load ( inputFile, true, &errorCode, NULL ); + if (ii) + isRaw=true; + else + ii = rtengine::InitialImage::load ( inputFile , false, &errorCode, NULL ); + if (!ii) { + errors++; + std::cerr << "Error loading file: "<< inputFile << std::endl; + continue; + } + + if (useDefault) { + if (isRaw) { + std::cout << " Merging default Raw profile" << std::endl; + rawParams->applyTo(¤tParams); + } + else { + std::cout << " Merging default Image 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 ); + 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 100644 index 000000000..870eeae7f --- /dev/null +++ b/rtgui/multilangmgr.cc @@ -0,0 +1,188 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 +#include "../rtengine/safegtk.h" +#ifdef WIN32 +// Desired auto detect function is Vista+ +#define _WIN32_WINNT 0x0600 +#include +#include +#undef _WIN32_WINNT +#endif + +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__) + langName = TranslateRFC2Language(std::setlocale(LC_CTYPE,"")); +#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=="cs") return "Czech"; + if (major=="ca") return "Catala"; + if (major=="fr") return "Francais"; + if (major=="de") return "Deutsch"; + if (major=="sr") return "Serbian (Cyrilic Characters)"; + if (major=="zh") + return (minor=="CN" || minor=="SG") ? "Chinese (Simplified)" : "Chinese (Traditional)"; + if (major=="da") return "Dansk"; + if (major=="es") return "Espanol"; + if (major=="el") return "Greek"; + if (major=="he") return "Hebrew"; + if (major=="it") return "Italian"; + if (major=="ja") return "Japanese"; + 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=="sk") return "Slovak"; + if (major=="fi") return "Suomi"; + if (major=="se") 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..8d783be36 --- /dev/null +++ b/rtgui/mycurve.cc @@ -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 . + */ +#include "mycurve.h" +#include "../rtengine/curves.h" +#include +#include + +MyCurve::MyCurve () : 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; + + 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 + signal_style_changed().connect( sigc::mem_fun(*this, &MyCurve::styleChanged) ); + + 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; +} + +void MyCurve::styleChanged (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..9eeff7edc --- /dev/null +++ b/rtgui/mycurve.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 _MYCURVE_ +#define _MYCURVE_ + +#include +#include +#include "curvelistener.h" +#include "cursormanager.h" +#include "coloredbar.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 MyCurve : public Gtk::DrawingArea, public BackBuffer, public ColorCaller { + + friend class MyCurveIdleHelper; + + protected: + CurveListener* listener; + ColoredBar *leftBar; + ColoredBar *bottomBar; + CursorShape cursor_type; + int graphX, graphY, graphW, graphH; /// 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 + std::vector< Point > point; + std::vector< Point > upoint; + std::vector< Point > 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; + + 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); + + // 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 styleChanged (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 (double identityValue=0.5) = 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..7c5c13b52 --- /dev/null +++ b/rtgui/mydiagonalcurve.cc @@ -0,0 +1,849 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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]; + + 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 = new rtengine::DiagonalCurve (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); + delete rtcurve; + return vector; +} + +void MyDiagonalCurve::interpolate () { + + prevGraphW = graphW; + prevGraphH = graphH; + int nbPoints = graphW-2; + point.resize (nbPoints); + std::vector vector = get_vector (nbPoints); + for (int i = 0; i < nbPoints; ++i) { + float currX = float(i)/float(nbPoints-1); + point.at(i).setCoords(float(graphX)+1.5f+float(graphW-3)*currX, float(graphY)-1.5f-float(graphH-3)*float(vector.at(i))); + } + upoint.clear (); + lpoint.clear (); + + if (curve.type==DCT_Parametric && activeParam>0) { + double tmp = curve.x.at(activeParam-1); + if (activeParam>=4) { + upoint.resize(nbPoints); + lpoint.resize(nbPoints); + curve.x.at(activeParam-1) = 100; + vector = get_vector (nbPoints); + for (int i = 0; i < nbPoints; ++i) { + float currX = float(i)/float(nbPoints-1); + upoint.at(i).setCoords(float(graphX)+1.5f+float(graphW-3)*currX, float(graphY)-1.5f-float(graphH-3)*float(vector.at(i))); + } + curve.x.at(activeParam-1) = -100; + vector = get_vector (nbPoints); + for (int i = 0; i < nbPoints; ++i) { + float currX = float(i)/float(nbPoints-1); + lpoint.at(i).setCoords(float(graphX)+1.5f+float(graphW-3)*currX, float(graphY)-1.5f-float(graphH-3)*float(vector.at(i))); + } + 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 + if (curveIsDirty || prevGraphW != graphW || prevGraphH != graphH || int(point.size()) != graphW-2) + interpolate (); + + 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 + if (curve.type==DCT_Parametric && activeParam>0 && lpoint.size()>1 && upoint.size()>1) { + cr->set_source_rgba (0.0, 0.0, 0.0, 0.15); + cr->move_to (upoint[0].x, upoint[0].y); + for (int i=1; i<(int)upoint.size(); i++) + cr->line_to (upoint[i].x, upoint[i].y); + cr->line_to (lpoint[lpoint.size()-1].x, lpoint[lpoint.size()-1].y); + for (int i=(int)lpoint.size()-2; i>=0; i--) + cr->line_to (lpoint[i].x, lpoint[i].y); + cr->line_to (upoint[0].x, upoint[0].y); + cr->fill (); + } + + 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.x[i], 0, 1, graphW); + double y1 = double(graphY)-1.5 - double(graphH-3)*points[pos-1]; // project (curve.y[i], 0, 1, graphH); + double x2 = double(graphX)+0.5 + double(graphW-3)*points[pos]; // project (curve.x[i], 0, 1, graphW); + double y2 = double(graphY)-1.5 - double(graphH-3)*points[pos+1]; // project (curve.y[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 (double(point.at(0).x), double(point.at(0).y)); + for (int i=1; i<(int)point.size(); i++) { + cr->line_to (double(point.at(i).x), double(point.at(i).y)); + } + 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[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) + 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[i]); // project (curve.x[i], 0, 1, graphW); + double y = double(graphY-1) - double((graphH-2) * curve.y[i]); // project (curve.y[i], 0, 1, graphH); + + cr->arc (x, y, RADIUS+0.5, 0, 2*M_PI); + cr->fill (); + } + } + 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; + int src, dst; + std::vector::iterator itx, ity; + + bool retval = false; + int num = (int)curve.x.size(); + + /* 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 false; + + 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); + 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 (event->button.button == 1) { + buttonPressed = true; + add_modal_grab (); + + // get the pointer position + getCursorPosition(event); + findClosestPoint(); + + new_type = CSMove; + if (distanceX > minDistanceX) { + /* insert a new control point */ + if (num > 0) { + if (clampedX > curve.x[closest_point]) + ++closest_point; + } + itx = curve.x.begin(); + ity = curve.y.begin(); + for (int i=0; ibutton.button == 1) { + buttonPressed = false; + /* get the pointer position */ + getCursorPosition(event); + 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[src] >= 0.0) { + curve.x[dst] = curve.x[src]; + curve.y[dst] = curve.y[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; + 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(event); + + 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 + new_type = CSArrow; + lit_point = -1; + } + else 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); + } + } + else { + // a point is being moved + + // bounds of the grabbed point + double leftBound = (grab_point == 0 ) ? 0. : curve.x[grab_point-1]; + double rightBound = (grab_point == num-1) ? 1. : curve.x[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[grab_point]; + double prevPosY = curve.y[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[grab_point] = -1.; + } + else if (ugpX <= leftDeletionBound && (grab_point > 0 && grab_point < (num-1))) { + curve.x[grab_point] = -1.; + } + else + // nextPosX is in bounds + curve.x[grab_point] = CLAMP(ugpX, leftBound, rightBound); + + // Handling limitations along Y axis + if (ugpY >= topDeletionBound && grab_point != 0 && grab_point != num-1) { + curve.x[grab_point] = -1.; + } + else if (ugpY <= bottomDeletionBound && grab_point != 0 && grab_point != num-1) { + curve.x[grab_point] = -1.; + } + else { + // snapping point to specific values + if (snapTo && curve.x[grab_point] != -1.) { + if (grab_point > 0 && grab_point < (curve.y.size()-1)) { + double prevX = curve.x[grab_point-1]; + double prevY = curve.y[grab_point-1]; + double nextX = curve.x[grab_point+1]; + double nextY = curve.y[grab_point+1]; + + double ratio = (curve.x[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[prevP], ugpY)) snapToElmt = prevP; + } + if (grab_point < (curve.y.size()-1)) { + int nextP = grab_point+1; + if (snapCoordinateY(curve.y[nextP], ugpY)) snapToElmt = nextP; + } + if (snapCoordinateY(1.0, ugpY)) snapToElmt = -3; + if (snapCoordinateY(curve.x[grab_point], ugpY)) snapToElmt = -2; + if (snapCoordinateY(0.0, ugpY)) snapToElmt = -1; + + curve.y[grab_point] = snapToValY; + } + else { + // nextPosY is in the bounds + curve.y[grab_point] = CLAMP(ugpY, 0.0, 1.0); + } + } + + if (curve.x[grab_point] != prevPosX || curve.y[grab_point] != prevPosY) { + // we recalculate the curve only if we have to + curveIsDirty = true; + setDirty(true); + draw (lit_point); + notifyListener (); + } + } + } + + retval = true; + break; + + default: + break; + } + if (new_type != cursor_type) { + cursor_type = new_type; + cursorManager.setCursor(cursor_type); + } + return retval; +} + +void MyDiagonalCurve::getCursorPosition(GdkEvent* event) { + int tx, ty; + int prevCursorX, prevCursorY; + double incrementX = 1. / double(graphW); + double incrementY = 1. / double(graphH); + + // getting the cursor position + switch (event->type) { + case (Gdk::MOTION_NOTIFY) : + if (event->motion.is_hint) { + get_window()->get_pointer (tx, ty, mod_type); + } + else { + tx = int(event->button.x); + ty = int(event->button.y); + mod_type = (Gdk::ModifierType)event->button.state; + } + break; + case (Gdk::BUTTON_PRESS) : + case (Gdk::BUTTON_RELEASE) : + tx = int(event->button.x); + ty = int(event->button.y); + mod_type = (Gdk::ModifierType)event->button.state; + 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[i] - clampedX; + double dY = curve.y[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[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[i]>=0) { + result.push_back (curve.x[i]); + result.push_back (curve.y[i]); + } + } + } + return result; +} + +void MyDiagonalCurve::setPoints (const std::vector& p) { + int ix = 0; + DiagonalCurveType t = (DiagonalCurveType)p[ix++]; + curve.type = t; + if (t==DCT_Parametric) { + curve.x.clear (); + curve.y.clear (); + for (size_t i=1; i(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(double identityValue) { + + 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..aebd01b08 --- /dev/null +++ b/rtgui/mydiagonalcurve.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 _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 + 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 getCursorPosition(GdkEvent* event); + void findClosestPoint(); + std::vector get_vector (int veclen); + + 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 (double identityValue=0.5); + void updateBackgroundHistogram (LUTu & hist); +}; + +#endif diff --git a/rtgui/myflatcurve.cc b/rtgui/myflatcurve.cc new file mode 100644 index 000000000..91241a30c --- /dev/null +++ b/rtgui/myflatcurve.cc @@ -0,0 +1,1275 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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]; + + 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 = new rtengine::FlatCurve (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 + delete rtcurve; + return convertedValues; +} + +void MyFlatCurve::interpolate () { + + prevGraphW = graphW; + prevGraphH = graphH; + int nbPoints = graphW-2; + point.resize (nbPoints); + std::vector vector = get_vector (nbPoints); + for (int i = 0; i < nbPoints; ++i) { + float currX = float(i)/float(nbPoints-1); + point.at(i).setCoords(float(graphX)+1.5f+float(graphW-3)*currX, float(graphY)-1.5f-float(graphH-3)*float(vector.at(i))); + } + upoint.clear (); + lpoint.clear (); + + curveIsDirty = false; +} + +void MyFlatCurve::draw () { + if (!isDirty()) { + return; + } + + Glib::RefPtr win = get_window(); + if (!surfaceCreated() || !win) + return; + + // re-calculate curve if dimensions changed + if (curveIsDirty || prevGraphW != graphW || prevGraphH != graphH || (int)point.size() != graphW-2) + 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 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[i] != -1.) { + int coloredLineWidth = min( max(75,graphW)/75, 8 ); + + cr->set_line_width (coloredLineWidth); + colorProvider->colorForValue(curve.x[i], 0.5, 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[i], double(graphY-1)); + cr->rel_line_to (0., -innerH); + cr->stroke (); + cr->set_line_width (coloredLineWidth); + + // draw the lit_point's horizontal line + 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); + } + + colorProvider->colorForValue(curve.x[i], curve.y[i], colorCallerId, this); + cr->set_source_rgb (ccRed, ccGreen, ccBlue); + + cr->move_to (double(graphX+1) , double(graphY-1) - innerH*curve.y[lit_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 ( (area&(FCT_Area_H|FCT_Area_V|FCT_Area_Point)) || editedHandle==FCT_EditedHandle_CPointUD ) { + // draw the lit_point's vertical line + if (editedHandle&(FCT_EditedHandle_CPointUD|FCT_EditedHandle_CPoint|FCT_EditedHandle_CPointY)) { + cr->set_line_width (2.0); + } + cr->move_to (double(graphX)+1 + innerW*curve.x[lit_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[lit_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 (lit_point!=-1 && getHandles(lit_point) && curve.x[lit_point]!=-1.) { + double x = double(graphX+1) + innerW*curve.x[lit_point]; + double y = double(graphY) - innerH*curve.y[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[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[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()); + cr->move_to (point.at(0).x, point.at(0).y); + for (int i=1; i<(int)point.size(); i++) + cr->line_to (double(point.at(i).x), double(point.at(i).y)); + cr->stroke (); + + // draw bullets + //if (curve.type!=FCT_Parametric) + for (int i = 0; i < (int)curve.x.size(); ++i) { + if (curve.x[i] != -1.) { + if (i == lit_point) { + if (colorProvider) { + colorProvider->colorForValue(curve.x[i], curve.y[i], colorCallerId, this); + cr->set_source_rgb (ccRed, ccGreen, ccBlue); + } + else + cr->set_source_rgb (1.0, 0.0, 0.0); + } + else if (i == snapToElmt) { + cr->set_source_rgb (1.0, 0.0, 0.0); + } + else if (curve.y[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[i]; // project (curve.x[i], 0, 1, graphW); + double y = double(graphY-1) - innerH * curve.y[i]; // project (curve.y[i], 0, 1, graphH); + + cr->arc (x, y, (double)RADIUS, 0, 2*M_PI); + cr->fill (); + } + } + // 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[n]; + leftTan = curve.leftTangent[n]; + rightTan = curve.rightTangent[n]; + + if (!n) { + // first point, the left handle is then computed with the last point's right handle + prevX = curve.x[N-1]-1.0; + nextX = curve.x[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[n-1]; + nextX = curve.x[0]+1.0; + } + else { + // last point, the right handle is then computed with the first point's left handle + prevX = curve.x[n-1]; + nextX = curve.x[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; + int src, dst; + 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(); + + minDistanceX = double(MIN_DISTANCE) / double(graphW-1); + minDistanceY = double(MIN_DISTANCE) / double(graphH-1); + + if ((graphW < 0) || (graphH < 0)) + return false; + + 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); + curveIsDirty = true; + } + draw (); + GdkRectangle *rectangle = &(event->expose.area); + copySurface(win, rectangle); + + retval = true; + break; + } + + case Gdk::BUTTON_PRESS: + //if (curve.type!=FCT_Parametric) { + if (event->button.button == 1) { + buttonPressed = true; + add_modal_grab (); + + // get the pointer position + getCursorPosition(event); + 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[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 == 1) { + buttonPressed = false; + enum MouseOverAreas prevArea = area; + 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[src] >= 0.0) { + curve.x[dst] = curve.x[src]; + curve.y[dst] = curve.y[src]; + curve.leftTangent[dst] = curve.leftTangent[src]; + curve.rightTangent[dst] = curve.rightTangent[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(event); + 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(event); + 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))) { + + bool sameSide = false; + + // display the handles + tanHandlesDisplayed = true; + + if (curve.x[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[lit_point] + 2.*minDistanceX; + sameSide = true; + } + else if (curve.x[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[lit_point] - 2.*minDistanceX; + sameSide = true; + } + else { + leftTanHandle.centerX = curve.x[lit_point] - 2.*minDistanceX; + rightTanHandle.centerX = curve.x[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) { + tanHandlesDisplayed = false; + } + + + 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 (); + } + break; + } + + case (FCT_EditedHandle_CPoint): + movePoint(true, true); + break; + + case (FCT_EditedHandle_CPointX): + movePoint(true, false); + break; + + case (FCT_EditedHandle_CPointY): + movePoint(false, true); + break; + + case (FCT_EditedHandle_LeftTan): { + double prevValue = curve.leftTangent[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[lit_point] = snapToValX; + } + else { + curve.leftTangent[lit_point] = ugpX; + } + + if (curve.leftTangent[lit_point] != prevValue) { + curveIsDirty = true; + setDirty(true); + draw (); + notifyListener (); + } + break; + } + + case (FCT_EditedHandle_RightTan): { + double prevValue = curve.rightTangent[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[lit_point] = snapToValX; + } + else { + curve.rightTangent[lit_point] = ugpX; + } + + if (curve.rightTangent[lit_point] != prevValue) { + curveIsDirty = true; + setDirty(true); + draw (); + notifyListener (); + } + break; + } + + // already processed before the "switch" instruction + //case (FCT_EditedHandle_CPointUD): + + default: + break; + } + } + + 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; + 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::movePoint(bool moveX, bool moveY) { + + // 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[lit_point]; + double prevPosY = curve.y[lit_point]; + + int nbPoints = (int)curve.x.size(); + + // left and right bound rely on curve periodicity + leftBound = (lit_point == 0 ) ? (periodic && !snapTo ? curve.x[nbPoints-1]-1. : 0.) : curve.x[lit_point-1]; + rightBound = (lit_point == nbPoints-1) ? (periodic && !snapTo ? curve.x[0]+1. : 1.) : curve.x[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[0] = snapToValX; + } + else if (lit_point==(nbPoints-1)) { + snapCoordinateX(1.0, ugpX); + curve.x[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[0]); + curve.y.push_back(curve.y[0]); + curve.leftTangent.push_back(curve.leftTangent[0]); + curve.rightTangent.push_back(curve.rightTangent[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[0] = curve.x[nbPoints]; + curve.y[0] = curve.y[nbPoints]; + curve.leftTangent[0] = curve.leftTangent[nbPoints]; + curve.rightTangent[0] = curve.rightTangent[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[lit_point] = -1.; + } + else if (ugpX <= leftDeletionBound && nbPoints>2 && !snapTo) { + curve.x[lit_point] = -1.; + } + else + // nextPosX is in bounds + curve.x[lit_point] = CLAMP(ugpX, leftBound, rightBound); + } + + if (moveY) { + + // we memorize the previous position of the point, for optimization purpose + ugpY += deltaY; + + // snapping point to specific values + if (snapTo && curve.x[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[prevP], ugpY)) snapToElmt = prevP; + } + else { + int prevP = lit_point-1; + if (snapCoordinateY(curve.y[prevP], ugpY)) snapToElmt = prevP; + } + + if (curve.y.size() > 2) { + if (lit_point == (curve.y.size()-1)) { + if (snapCoordinateY(curve.y[0], ugpY)) snapToElmt = 0; + } + else { + int nextP = lit_point+1; + if (snapCoordinateY(curve.y[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[lit_point] = snapToValY; + } + + // Handling limitations along Y axis + if (ugpY >= topDeletionBound && nbPoints>2) { + if (curve.x[lit_point] != -1.) { + deletedPointX = curve.x[lit_point]; + curve.x[lit_point] = -1.; + curve.y[lit_point] = ugpY; // This is only to force the redraw of the curve + } + } + else if (ugpY <= bottomDeletionBound && nbPoints>2) { + if (curve.x[lit_point] != -1.) { + deletedPointX = curve.x[lit_point]; + curve.x[lit_point] = -1.; + curve.y[lit_point] = ugpY; // This is only to force the redraw of the curve + } + } + else { + // nextPosY is in the bounds + if (!snapTo) curve.y[lit_point] = CLAMP(ugpY, 0.0, 1.0); + if (!moveX && curve.x[lit_point] == -1.) { + // bring back the X value of the point if it reappear + curve.x[lit_point] = deletedPointX; + } + } + } + + if (curve.x[lit_point] != prevPosX || curve.y[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(GdkEvent* event) { + int tx, ty; + int prevCursorX, prevCursorY; + double incrementX = 1. / double(graphW); + double incrementY = 1. / double(graphH); + + switch (event->type) { + case (Gdk::MOTION_NOTIFY) : + if (event->motion.is_hint) { + get_window()->get_pointer (tx, ty, mod_type); + } + else { + tx = (int)event->button.x; + ty = (int)event->button.y; + mod_type = (Gdk::ModifierType)event->button.state; + } + break; + case (Gdk::BUTTON_PRESS) : + case (Gdk::BUTTON_RELEASE) : + tx = (int)event->button.x; + ty = (int)event->button.y; + mod_type = (Gdk::ModifierType)event->button.state; + 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[i] != -1) { + dX = curve.x[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[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[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[i]>=0) { + result.push_back (curve.x[i]); + result.push_back (curve.y[i]); + result.push_back (curve.leftTangent[i]); + result.push_back (curve.rightTangent[i]); + } + } + //} + return result; +} + +void MyFlatCurve::setPoints (const std::vector& p) { + int ix = 0; + 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::setType (FlatCurveType t) { + + curve.type = t; + setDirty(true); +} + +void MyFlatCurve::reset(double identityValue) { + calcDimensions(); + + 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..7f9db613f --- /dev/null +++ b/rtgui/myflatcurve.h @@ -0,0 +1,125 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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); + void defaultCurve (double iVal=0.5); + void interpolate (); + void getCursorPosition(GdkEvent* event); + void getMouseOverArea (); + bool getHandles(int n); + std::vector get_vector (int veclen); + + 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 (double identityValue=0.5); + //void updateBackgroundHistogram (unsigned int* hist); +}; + +#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..2418c19a2 --- /dev/null +++ b/rtgui/navigator.cc @@ -0,0 +1,182 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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" + +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); + + 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 ()); + + Gtk::Table* table = Gtk::manage (new Gtk::Table (3, 3)); + table->attach (*R, 0, 1, 0, 1, Gtk::EXPAND, Gtk::SHRINK, 0, 0); + table->attach (*G, 0, 1, 1, 2, Gtk::EXPAND, Gtk::SHRINK, 0, 0); + table->attach (*B, 0, 1, 2, 3, Gtk::EXPAND, Gtk::SHRINK, 0, 0); + table->attach (*H, 1, 2, 0, 1, Gtk::EXPAND, Gtk::SHRINK, 0, 0); + table->attach (*S, 1, 2, 1, 2, Gtk::EXPAND, Gtk::SHRINK, 0, 0); + table->attach (*V, 1, 2, 2, 3, Gtk::EXPAND, Gtk::SHRINK, 0, 0); + table->attach (*LAB_L, 2, 3, 0, 1, Gtk::EXPAND, Gtk::SHRINK, 0, 0); + table->attach (*LAB_A, 2, 3, 1, 2, Gtk::EXPAND, Gtk::SHRINK, 0, 0); + table->attach (*LAB_B, 2, 3, 2, 3, Gtk::EXPAND, Gtk::SHRINK, 0, 0); + + mbox->pack_start (*table, Gtk::PACK_SHRINK, 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_R_NA")); + G->set_text (M("NAVIGATOR_G_NA")); + B->set_text (M("NAVIGATOR_B_NA")); + H->set_text (M("NAVIGATOR_H_NA")); + S->set_text (M("NAVIGATOR_S_NA")); + V->set_text (M("NAVIGATOR_V_NA")); + LAB_A->set_text (M("NAVIGATOR_LAB_A_NA")); + LAB_B->set_text (M("NAVIGATOR_LAB_B_NA")); + LAB_L->set_text (M("NAVIGATOR_LAB_L_NA")); +} + +// if !validPos then x/y contain the full image size +void Navigator::pointerMoved (bool validPos, Glib::ustring profile, 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::compose (M("NAVIGATOR_R_VALUE"), Glib::ustring::format(std::fixed, std::setprecision(1), r*100.f/255.f) + Glib::ustring("%"))); + G->set_text (Glib::ustring::compose (M("NAVIGATOR_G_VALUE"), Glib::ustring::format(std::fixed, std::setprecision(1), g*100.f/255.f) + Glib::ustring("%"))); + B->set_text (Glib::ustring::compose (M("NAVIGATOR_B_VALUE"), 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::compose (M("NAVIGATOR_H_VALUE"), Glib::ustring::format(std::fixed, std::setprecision(1), h*360.f) + Glib::ustring("\xc2\xb0"))); + S->set_text (Glib::ustring::compose (M("NAVIGATOR_S_VALUE"), Glib::ustring::format(std::fixed, std::setprecision(1), s*100.f) + Glib::ustring("%"))); + V->set_text (Glib::ustring::compose (M("NAVIGATOR_V_VALUE"), Glib::ustring::format(std::fixed, std::setprecision(1), v*100.f) + Glib::ustring("%"))); + int LAB_a, LAB_b, LAB_l; + //rgb2lab (r, g, b, LAB_l, LAB_a, LAB_b); + rgb2lab (profile, r, g, b, LAB_l, LAB_a, LAB_b); // TODO: Really sure this function works? + + LAB_A->set_text (Glib::ustring::compose (M("NAVIGATOR_LAB_A_VALUE"), LAB_a)); + LAB_B->set_text (Glib::ustring::compose (M("NAVIGATOR_LAB_B_VALUE"), LAB_b)); + LAB_L->set_text (Glib::ustring::compose (M("NAVIGATOR_LAB_L_VALUE"), LAB_l)); + } +} + + +void Navigator::rgb2lab (Glib::ustring profile, int r, int g, int b, int &LAB_l, int &LAB_a, int &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; + + if (profile=="sRGB") {//apply sRGB inverse gamma + + // +// if you want display = working space +// today as the gamma output can not be configured +// it is better that the user has the gamma of the output space + 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; + } +// if you want display = output space + 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 {// 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); + } + + /*for (int i=0; iworkingSpaceMatrix (profile); + + 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?pow (var_X, 1.0/3.0):( ka * var_X + 16.0) / 116.0 ; + varyy = var_Y>ep?pow (var_Y, 1.0/3.0):( ka * var_Y + 16.0) / 116.0 ; + varzz = var_Z>ep?pow (var_Z, 1.0/3.0):( 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..207a9daf3 --- /dev/null +++ b/rtgui/navigator.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 _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; + + void rgb2lab (Glib::ustring profile, int r, int g, int b, int &LAB_l, int &LAB_a, int &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, 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..548e9f9e5 --- /dev/null +++ b/rtgui/options.cc @@ -0,0 +1,1255 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 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 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 (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; + windowMaximized = true; + saveAsDialogWidth = 920; + saveAsDialogHeight = 680; + savesParamsAtExit = true; + saveFormat.format = "jpg"; + saveFormat.jpegQuality = 90; + saveFormat.jpegSubSamp = 2; + saveFormat.pngCompression = 6; + saveFormat.pngBits = 8; + saveFormat.tiffBits = 8; + saveFormat.tiffUncompressed = true; + saveFormat.saveParams = true; + + saveFormatBatch.format = "jpg"; + saveFormatBatch.jpegQuality = 90; + 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; + dirBrowserWidth = 260; + dirBrowserHeight = 350; + preferencesWidth = 800; + preferencesHeight = 0; + toolPanelWidth = 390; + browserToolPanelWidth = 430; + browserToolPanelHeight = 600; + historyPanelWidth = 330; + lastScale = 5; + panAccelFactor = 5; + 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 = false; // 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 = 400; + 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; + internalThumbIfUntouched = true; // if TRUE, only fast, internal preview images are taken if the image is not edited yet + showFileNames = true; + tabbedUI = false; + mainNBVertical = true; + multiDisplayMode = 0; + tunnelMetaData = true; + histogramPosition = 1; + histogramBar = true; + histogramFullMode = false; + + rgbDenoiseThreadLimit = 0; + + filledProfile = true; + + showProfileSelector = true; + FileBrowserToolbarSingleRow = false; + hideTPVScrollbar = false; + UseIconNoText = true; + whiteBalanceSpotSize = 8; + squareDetailWindow = true; + 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_raw_all_enhance = true; + fastexport_bypass_raw_ccSteps = true; + fastexport_bypass_raw_dcb_iterations = true; + fastexport_bypass_raw_dcb_enhance = true; + fastexport_bypass_raw_lmmse_iterations = true; + fastexport_bypass_raw_ca = true; + fastexport_bypass_raw_linenoise = true; + fastexport_bypass_raw_greenthresh = true; + fastexport_bypass_raw_df = true; + fastexport_bypass_raw_ff = true; + fastexport_raw_dmethod = "fast"; + 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; + + cutOverlayBrush = std::vector (4); + cutOverlayBrush[3] = 0.667; // :-p + + 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_BLACKWHITE_HUES + 0, // ADDSET_BLACKWHITE_GAMMA + 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_BADPIX + 0, // ADDSET_CAT_JLIGHT + 0, // ADDSET_CAT_CHROMA + 0, // ADDSET_CAT_CONTRAST + 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 + + }; + 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.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.ciecamfloat = true; + rtSettings.protectred = 60; + rtSettings.protectredh = 0.3; + rtSettings.CRI_color =0; + rtSettings.autocielab=true; +// 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 = ""; + lastPFCurvesDir = ""; + lastHsvCurvesDir = ""; + lastToneCurvesDir = ""; + lastVibranceCurvesDir = ""; + lastProfilingReferenceDir = ""; + lastBWCurvesDir = ""; + +} + +Options* Options::copyFrom (Options* other) { + *this = *other; + return this; +} + +void Options::filterOutParsedExtensions () { + parsedExtensions.clear(); + for (unsigned int i=0; i 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", "ShowFileNames", showFileNames ); + 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 ("Clipping Indication", "HighlightThreshold", highlightThreshold); + keyFile.set_integer ("Clipping Indication", "ShadowThreshold", shadowThreshold); + keyFile.set_boolean ("Clipping Indication", "BlinkClipped", blinkClipped); + + keyFile.set_integer ("Performance", "RgbDenoiseThreadLimit", rgbDenoiseThreadLimit); + + keyFile.set_string ("Output", "Format", saveFormat.format); + keyFile.set_integer ("Output", "JpegQuality", saveFormat.jpegQuality); + keyFile.set_integer ("Output", "JpegSubSamp", saveFormat.jpegSubSamp); + keyFile.set_integer ("Output", "PngCompression", saveFormat.pngCompression); + keyFile.set_integer ("Output", "PngBps", saveFormat.pngBits); + keyFile.set_integer ("Output", "TiffBps", saveFormat.tiffBits); + keyFile.set_boolean ("Output", "TiffUncompressed", saveFormat.tiffUncompressed); + keyFile.set_boolean ("Output", "SaveProcParams", saveFormat.saveParams); + + keyFile.set_string ("Output", "FormatBatch", saveFormatBatch.format); + keyFile.set_integer ("Output", "JpegQualityBatch", saveFormatBatch.jpegQuality); + keyFile.set_integer ("Output", "JpegSubSampBatch", saveFormatBatch.jpegSubSamp); + keyFile.set_integer ("Output", "PngCompressionBatch", saveFormatBatch.pngCompression); + keyFile.set_integer ("Output", "PngBpsBatch", saveFormatBatch.pngBits); + keyFile.set_integer ("Output", "TiffBpsBatch", saveFormatBatch.tiffBits); + keyFile.set_boolean ("Output", "TiffUncompressedBatch", saveFormatBatch.tiffUncompressed); + keyFile.set_boolean ("Output", "SaveProcParamsBatch", saveFormatBatch.saveParams); + + keyFile.set_string ("Output", "PathTemplate", savePathTemplate); + keyFile.set_string ("Output", "PathFolder", savePathFolder); + keyFile.set_boolean ("Output", "AutoSuffix", autoSuffix); + keyFile.set_boolean ("Output", "ForceFormatOpts", forceFormatOpts); + keyFile.set_integer ("Output", "SaveMethodNum", saveMethodNum); + keyFile.set_boolean ("Output", "UsePathTemplate", saveUsePathTemplate); + keyFile.set_string ("Output", "LastSaveAsPath", lastSaveAsPath); + keyFile.set_boolean ("Output", "OverwriteOutputFile", overwriteOutputFile); + keyFile.set_boolean ("Output", "TunnelMetaData", tunnelMetaData); + + keyFile.set_string ("Profiles", "Directory", profilePath); + keyFile.set_boolean ("Profiles", "UseBundledProfiles", useBundledProfiles); + keyFile.set_string ("Profiles", "LoadSaveProfilePath", loadSaveProfilePath); + keyFile.set_string ("Profiles", "RawDefault", defProfRaw); + keyFile.set_string ("Profiles", "ImgDefault", defProfImg); + keyFile.set_boolean ("Profiles", "FilledProfile", filledProfile); + keyFile.set_boolean ("Profiles", "SaveParamsWithFile", saveParamsFile); + keyFile.set_boolean ("Profiles", "SaveParamsToCache", saveParamsCache); + keyFile.set_integer ("Profiles", "LoadParamsFromLocation", paramsLoadLocation); + keyFile.set_string ("Profiles", "CustomProfileBuilderPath", CPBPath); + keyFile.set_integer ("Profiles", "CustomProfileBuilderKeys", CPBKeys); + + keyFile.set_string ("GUI", "Font", font); + keyFile.set_integer ("GUI", "WindowWidth", windowWidth); + keyFile.set_integer ("GUI", "WindowHeight", windowHeight); + keyFile.set_boolean ("GUI", "WindowMaximized", windowMaximized); + keyFile.set_integer ("GUI", "DirBrowserWidth", dirBrowserWidth); + keyFile.set_integer ("GUI", "DirBrowserHeight", dirBrowserHeight); + keyFile.set_integer ("GUI", "PreferencesWidth", preferencesWidth); + keyFile.set_integer ("GUI", "PreferencesHeight", preferencesHeight); + keyFile.set_integer ("GUI", "SaveAsDialogWidth", saveAsDialogWidth); + keyFile.set_integer ("GUI", "SaveAsDialogHeight", saveAsDialogHeight); + keyFile.set_integer ("GUI", "ToolPanelWidth", toolPanelWidth); + keyFile.set_integer ("GUI", "BrowserToolPanelWidth", browserToolPanelWidth); + keyFile.set_integer ("GUI", "BrowserToolPanelHeight", browserToolPanelHeight); + keyFile.set_integer ("GUI", "HistoryPanelWidth", historyPanelWidth); + keyFile.set_integer ("GUI", "LastPreviewScale", lastScale); + keyFile.set_integer ("GUI", "PanAccelFactor", panAccelFactor); + keyFile.set_integer ("GUI", "LastCropSize", lastCropSize); + keyFile.set_boolean ("GUI", "ShowHistory", showHistory); + keyFile.set_integer ("GUI", "ShowFilePanelState", showFilePanelState); + keyFile.set_boolean ("GUI", "ShowInfo", showInfo); + keyFile.set_boolean ("GUI", "MainNBVertical", mainNBVertical); + keyFile.set_boolean ("GUI", "ShowClippedHighlights", showClippedHighlights); + keyFile.set_boolean ("GUI", "ShowClippedShadows", showClippedShadows); + keyFile.set_integer ("GUI", "FrameColor", bgcolor); + keyFile.set_boolean ("GUI", "ProcessingQueueEnbled", procQueueEnabled); + Glib::ArrayHandle tpopen = tpOpen; + keyFile.set_integer_list ("GUI", "ToolPanelsExpanded", tpopen); + keyFile.set_integer ("GUI", "MultiDisplayMode", multiDisplayMode); + keyFile.set_double_list ("GUI", "CutOverlayBrush", cutOverlayBrush); + keyFile.set_integer ("GUI", "HistogramPosition", histogramPosition); + keyFile.set_boolean ("GUI", "HistogramBar", histogramBar); + keyFile.set_boolean ("GUI", "HistogramFullMode", histogramFullMode); + keyFile.set_boolean ("GUI", "ShowProfileSelector", showProfileSelector); + keyFile.set_boolean ("GUI", "SquareDetailWindow", squareDetailWindow); + keyFile.set_boolean ("GUI", "FileBrowserToolbarSingleRow", FileBrowserToolbarSingleRow); + keyFile.set_boolean ("GUI", "HideTPVScrollbar", hideTPVScrollbar); + keyFile.set_boolean ("GUI", "UseIconNoText", UseIconNoText); + + //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_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_boolean ("Color Management", "Ciebadpixgauss", rtSettings.ciebadpixgauss); + + 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_raw_all_enhance" , fastexport_bypass_raw_all_enhance ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_ccSteps" , fastexport_bypass_raw_ccSteps ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_dcb_iterations" , fastexport_bypass_raw_dcb_iterations); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_dcb_enhance" , fastexport_bypass_raw_dcb_enhance ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_lmmse_iterations" , fastexport_bypass_raw_lmmse_iterations); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_ca" , fastexport_bypass_raw_ca ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_linenoise" , fastexport_bypass_raw_linenoise ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_greenthresh" , fastexport_bypass_raw_greenthresh ); + 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_raw_dmethod" , fastexport_raw_dmethod ); + 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", "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; + } +} + +void Options::load () { + + // Find the application data path + +#ifdef WIN32 + const gchar* dataPath; + Glib::ustring dPath; + + dataPath = g_getenv("RT_CACHE"); + if (dataPath != NULL) + rtdir = Glib::ustring(dataPath); + else { + 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 + + // 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")); + + // 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")); + } + // Modify the path of the cache folder to the user's personal folder +#ifdef WIN32 + cacheBaseDir = Glib::build_filename(rtdir, "cache"); +#else + cacheBaseDir = Glib::build_filename(Glib::ustring(g_get_user_cache_dir()), Glib::ustring(CACHEFOLDERNAME)); +#endif + +#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 + } + + // 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); +} + +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..e77f98e22 --- /dev/null +++ b/rtgui/options.h @@ -0,0 +1,292 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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; +}; + +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}; + +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; + 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; + int historyPanelWidth; + Glib::ustring font; + int windowWidth; + int windowHeight; + bool windowMaximized; + 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 showFileNames; + bool tabbedUI; + int previewSizeTab,previewSizeBrowser; + int multiDisplayMode; // 0=none, 1=Edit panels on other display + std::vector cutOverlayBrush; // 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 + bool histogramBar; + bool histogramFullMode; + bool showProfileSelector; + bool squareDetailWindow; + bool FileBrowserToolbarSingleRow; + bool hideTPVScrollbar; + bool UseIconNoText; + int whiteBalanceSpotSize; + + // Performance options + int rgbDenoiseThreadLimit; // maximum number of threads for the denoising tool ; 0 = use the maximum available + + bool filledProfile; // Used as reminder for the ProfilePanel "mode" + + 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_raw_all_enhance; + bool fastexport_bypass_raw_ccSteps; + bool fastexport_bypass_raw_dcb_iterations; + bool fastexport_bypass_raw_dcb_enhance; + bool fastexport_bypass_raw_lmmse_iterations; + bool fastexport_bypass_raw_ca; + bool fastexport_bypass_raw_linenoise; + bool fastexport_bypass_raw_greenthresh; + bool fastexport_bypass_raw_df; + bool fastexport_bypass_raw_ff; + Glib::ustring fastexport_raw_dmethod; + 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 lastPFCurvesDir; + Glib::ustring lastHsvCurvesDir; + Glib::ustring lastToneCurvesDir; + Glib::ustring lastVibranceCurvesDir; + Glib::ustring lastProfilingReferenceDir; + Glib::ustring lastBWCurvesDir; + + Options (); + + Options* copyFrom (Options* other); + void filterOutParsedExtensions (); + void setDefaults (); + int readFromFile (Glib::ustring fname); + int saveToFile (Glib::ustring fname); + static void 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 paramFileExtension; + +#endif diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc new file mode 100644 index 000000000..9e552a9e8 --- /dev/null +++ b/rtgui/paramsedited.cc @@ -0,0 +1,890 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 () { + + set (false); +} + +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; + 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; + 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.luma = v; + dirpyrDenoise.Ldetail = v; + dirpyrDenoise.chroma = v; + dirpyrDenoise.redchro = v; + dirpyrDenoise.bluechro = v; + dirpyrDenoise.gamma = v; + dirpyrDenoise.dmethod = v; + edgePreservingDecompositionUI.enabled = v; + edgePreservingDecompositionUI.Strength = v; + edgePreservingDecompositionUI.EdgeStopping = v; + edgePreservingDecompositionUI.Scale = v; + edgePreservingDecompositionUI.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; + + 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.ccSteps = v; + raw.dmethod = v; + raw.dcbIterations = v; + raw.dcbEnhance = v; + raw.lmmseIterations = v; + + //raw.allEnhance = v; + raw.caCorrection = v; + raw.caBlue = v; + raw.caRed = v; + raw.greenEq = v; + raw.hotDeadPixelFilter = v; + raw.hotDeadPixelThresh = v; + raw.linenoise = v; + raw.darkFrame = v; + raw.dfAuto = v; + raw.ff_file = v; + raw.ff_AutoSelect = v; + raw.ff_BlurRadius = v; + raw.ff_BlurType = v; + raw.exPos = v; + raw.exPreser = v; + raw.exBlackzero = v; + raw.exBlackone = v; + raw.exBlacktwo = v; + raw.exBlackthree = v; + raw.exTwoGreen=v; + + dirpyrequalizer.enabled = v; + for(int i = 0; i < 5; i++) { + dirpyrequalizer.mult[i] = v; + } + dirpyrequalizer.threshold = v; + hsvequalizer.hcurve = v; + hsvequalizer.scurve = v; + hsvequalizer.vcurve = 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::isUnchanged() const { + return ccSteps && dmethod && dcbIterations && dcbEnhance && lmmseIterations/*&& allEnhance*/ && caCorrection && caRed && caBlue && greenEq + && hotDeadPixelFilter && hotDeadPixelThresh && linenoise && darkFrame && dfAuto && ff_file && ff_AutoSelect && ff_BlurRadius && ff_BlurType + && exPos && exPreser && exBlackzero && exBlackone && exBlacktwo && exBlackthree && exTwoGreen; +} + +bool LensProfParamsEdited::isUnchanged() const { + return lcpFile; +} diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h new file mode 100644 index 000000000..3ba0bc8bb --- /dev/null +++ b/rtgui/paramsedited.h @@ -0,0 +1,532 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 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 Ldetail; + bool luma; + bool chroma; + bool redchro; + bool bluechro; + bool gamma; +// bool perform; + bool dmethod; +}; + +class EPDParamsEdited{ +public: + bool enabled; + bool Strength; + 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; +}; + +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 blendCMSMatrix; + bool dcpIlluminant; + bool working; + bool output; + bool gamma; + bool gampos; + bool slpos; + bool gamfree; + bool freegamma; +}; + +class DirPyrEqualizerParamsEdited { + + public: + bool enabled; + bool mult[5]; + bool threshold; +}; + +class HSVEqualizerParamsEdited { + + public: + bool hcurve; + bool scurve; + bool vcurve; +}; + +class RAWParamsEdited { + + public: + bool ccSteps; + bool dmethod; + bool dcbIterations; + bool dcbEnhance; + bool lmmseIterations; + //bool allEnhance; + bool caCorrection; + bool caRed; + bool caBlue; + bool greenEq; + bool hotDeadPixelFilter; + bool hotDeadPixelThresh; + bool linenoise; + bool darkFrame; + bool dfAuto; + bool ff_file; + bool ff_AutoSelect; + bool ff_BlurRadius; + bool ff_BlurType; + bool exPos; + bool exPreser; + bool exBlackzero; + bool exBlackone; + bool exBlacktwo; + bool exBlackthree; + bool exTwoGreen; + + bool isUnchanged() const; +}; + +class ParamsEdited { + + public: + GeneralParamsEdited general; + ToneCurveParamsEdited toneCurve; + LCurveParamsEdited labCurve; + RGBCurvesParamsEdited rgbCurves; + SharpeningParamsEdited sharpening; + SharpenEdgeParamsEdited sharpenEdge; + SharpenMicroParamsEdited sharpenMicro; + VibranceParamsEdited vibrance; + ColorAppearanceParamsEdited colorappearance; + //ColorBoostParamsEdited colorBoost; + WBParamsEdited wb; + //ColorShiftParamsEdited colorShift; + //LumaDenoiseParamsEdited lumaDenoise; + //ColorDenoiseParamsEdited colorDenoise; + DefringeParamsEdited defringe; + DirPyrDenoiseParamsEdited dirpyrDenoise; + EPDParamsEdited edgePreservingDecompositionUI; + 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; + HSVEqualizerParamsEdited hsvequalizer; + bool exif; + bool iptc; + + ParamsEdited (); + + 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..16531a029 --- /dev/null +++ b/rtgui/partialpastedlg.cc @@ -0,0 +1,681 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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); + + 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"); + metaicm = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_METAICMGROUP"))); + metaicm ->set_name("partialPasteHeader"); + raw = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWGROUP"))); + raw ->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 color: + 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"))); + rgbcurves = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RGBCURVES"))); + + // 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 metaicm: + exifch = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_EXIFCHANGES"))); + iptc = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_IPTCINFO"))); + icm = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_ICMSETTINGS"))); + gam = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_ICMGAMMA"))); + + // 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_hotdeadpix_filt = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT"))); + raw_linenoise = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PREPROCESS_LINEDENOISE"))); + raw_greenthresh = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PREPROCESS_GREENEQUIL"))); + raw_dmethod = 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"))); + + Gtk::VBox* vboxes[7]; + Gtk::HSeparator* hseps[7]; + for (int i=0; i<7; 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"); + } + + 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); + + 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); + //vboxes[1]->pack_start (*waveq, Gtk::PACK_SHRINK, 2); + + vboxes[2]->pack_start (*color, Gtk::PACK_SHRINK, 2); + vboxes[2]->pack_start (*hseps[2], 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 (*rgbcurves, Gtk::PACK_SHRINK, 2); + + 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); + + 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); + + vboxes[5]->pack_start (*metaicm, Gtk::PACK_SHRINK, 2); + vboxes[5]->pack_start (*hseps[5], Gtk::PACK_SHRINK, 2); + vboxes[5]->pack_start (*exifch, Gtk::PACK_SHRINK, 2); + vboxes[5]->pack_start (*iptc, Gtk::PACK_SHRINK, 2); + vboxes[5]->pack_start (*icm, Gtk::PACK_SHRINK, 2); + vboxes[5]->pack_start (*gam, Gtk::PACK_SHRINK, 2); + + vboxes[6]->pack_start (*raw, Gtk::PACK_SHRINK, 2); + vboxes[6]->pack_start (*hseps[6], Gtk::PACK_SHRINK, 2); + vboxes[6]->pack_start (*raw_dmethod, 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_hotdeadpix_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 (*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); + + 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]); + for (int i=3; i<6; i++) + vbCol2->pack_start (*vboxes[i]); + for (int i=6; i<7; i++) + vbCol3->pack_start (*vboxes[i]); + + Gtk::VBox* vbtop = Gtk::manage (new Gtk::VBox ()); + vbtop->pack_start (*everything, Gtk::PACK_SHRINK, 2); + vbtop->pack_start (*(Gtk::manage (new Gtk::HSeparator ()))); + vbtop->set_border_width (8); + + get_vbox()->pack_start (*vbtop); + + 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); + + get_vbox()->pack_start (*hbmain); + + // 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)); + metaicmConn = metaicm->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::metaicmToggled)); + rawConn = raw->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::rawToggled)); + + 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)); + //waveqConn = waveq->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)); + + 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)); + rgbcurvesConn = rgbcurves->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(*metaicm, &Gtk::CheckButton::set_inconsistent), true)); + iptcConn = iptc->signal_toggled().connect (sigc::bind (sigc::mem_fun(*metaicm, &Gtk::CheckButton::set_inconsistent), true)); + icmConn = icm->signal_toggled().connect (sigc::bind (sigc::mem_fun(*metaicm, &Gtk::CheckButton::set_inconsistent), true)); + gamcsconn = gam->signal_toggled().connect (sigc::bind (sigc::mem_fun(*metaicm, &Gtk::CheckButton::set_inconsistent), true)); + + raw_dmethodConn = raw_dmethod->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_hotdeadpix_filtConn = raw_hotdeadpix_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)); + + 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); + metaicmConn.block (true); + rawConn.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()); + metaicm->set_active(everything->get_active()); + raw->set_active(everything->get_active()); + + //toggle group children + PartialPasteDlg::basicToggled (); + PartialPasteDlg::detailToggled (); + PartialPasteDlg::colorToggled (); + PartialPasteDlg::lensToggled (); + PartialPasteDlg::compositionToggled (); + PartialPasteDlg::metaicmToggled (); + PartialPasteDlg::rawToggled (); + + basicConn.block (false); + detailConn.block (false); + colorConn.block (false); + lensConn.block (false); + compositionConn.block (false); + metaicmConn.block (false); + rawConn.block (false); +} + +void PartialPasteDlg::rawToggled () { + + raw_dmethodConn.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_hotdeadpix_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); + + raw->set_inconsistent (false); + + raw_dmethod->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_hotdeadpix_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 ()); + + raw_dmethodConn.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_hotdeadpix_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); +} + +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); + //waveqConn.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 ()); + //waveq->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); + //waveqConn.block (false); +} + +void PartialPasteDlg::colorToggled () { + + vibranceConn.block (true); + chmixerConn.block (true); + chmixerbwConn.block (true); + hsveqConn.block (true); + rgbcurvesConn.block (true); + gamcsconn.block (true); + color->set_inconsistent (false); + + vibrance->set_active (color->get_active ()); + chmixer->set_active (color->get_active ()); + blackwhite->set_active (color->get_active ()); + hsveq->set_active (color->get_active ()); + rgbcurves->set_active (color->get_active ()); + icm->set_active (color->get_active ()); + + vibranceConn.block (false); + chmixerbwConn.block (false); + chmixerConn.block (false); + hsveqConn.block (false); + rgbcurvesConn.block (false); + gamcsconn.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::metaicmToggled () { + + exifchConn.block (true); + iptcConn.block (true); + icmConn.block (true); + gamcsconn.block (true); + metaicm->set_inconsistent (false); + + exifch->set_active (metaicm->get_active ()); + iptc->set_active (metaicm->get_active ()); + icm->set_active (metaicm->get_active ()); + gam->set_active (metaicm->get_active ()); + + exifchConn.block (false); + iptcConn.block (false); + icmConn.block (false); + gamcsconn.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; // Contains the initial information about the loaded values + if (srcPE) { + filterPE = *srcPE; + } + else { + // By default, everything has to be copied + filterPE.set(true); + } + + + // 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.edgePreservingDecompositionUI = falsePE.edgePreservingDecompositionUI; + 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 (!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 (!rgbcurves->get_active ()) filterPE.rgbCurves = falsePE.rgbCurves; + if (!icm->get_active ()) filterPE.icm = falsePE.icm; + + 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 (!icm->get_active ()) filterPE.icm = falsePE.icm; + + if (!raw_dmethod->get_active ()) filterPE.raw.dmethod = falsePE.raw.dmethod; + if (!raw_ccSteps->get_active ()) filterPE.raw.ccSteps = falsePE.raw.ccSteps; + if (!raw_dcb_iterations->get_active ()) filterPE.raw.dcbIterations = falsePE.raw.dcbIterations; + if (!raw_dcb_enhance->get_active ()) filterPE.raw.dcbEnhance = falsePE.raw.dcbEnhance; + //if (!raw_all_enhance->get_active ()) filterPE.raw.allEnhance = falsePE.raw.allEnhance; + if (!raw_lmmse_iterations->get_active ()) filterPE.raw.lmmseIterations = falsePE.raw.lmmseIterations; + + if (!raw_expos->get_active ()) filterPE.raw.exPos = falsePE.raw.exPos; + if (!raw_preser->get_active ()) filterPE.raw.exPreser = falsePE.raw.exPreser; + if (!raw_black->get_active ()) { filterPE.raw.exBlackzero = falsePE.raw.exBlackzero; + filterPE.raw.exBlackone = falsePE.raw.exBlackone; + filterPE.raw.exBlacktwo = falsePE.raw.exBlacktwo; + filterPE.raw.exBlackthree = falsePE.raw.exBlackthree; + filterPE.raw.exTwoGreen = falsePE.raw.exTwoGreen; } + 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_hotdeadpix_filt->get_active ()) { filterPE.raw.hotDeadPixelFilter = falsePE.raw.hotDeadPixelFilter; + filterPE.raw.hotDeadPixelThresh = falsePE.raw.hotDeadPixelThresh; } + if (!raw_linenoise->get_active ()) filterPE.raw.linenoise = falsePE.raw.linenoise; + if (!raw_greenthresh->get_active ()) filterPE.raw.greenEq = falsePE.raw.greenEq; + 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 (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..206a23ca6 --- /dev/null +++ b/rtgui/partialpastedlg.h @@ -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 . + */ +#ifndef _PARTIALPASTEDLG_ +#define _PARTIALPASTEDLG_ + +#include +#include "../rtengine/rtengine.h" + +class PartialPasteDlg : public Gtk::Dialog { + + public: + + Gtk::CheckButton* everything; + + // main groups: + Gtk::CheckButton* basic; + Gtk::CheckButton* detail; + Gtk::CheckButton* color; + Gtk::CheckButton* lens; + Gtk::CheckButton* composition; + Gtk::CheckButton* metaicm; + Gtk::CheckButton* raw; + + // 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 color: + Gtk::CheckButton* vibrance; + Gtk::CheckButton* chmixer; + Gtk::CheckButton* blackwhite; + Gtk::CheckButton* hsveq; + Gtk::CheckButton* rgbcurves; + // Gtk::CheckButton* icm; + + // 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 metaicm: + Gtk::CheckButton* exifch; + Gtk::CheckButton* iptc; + Gtk::CheckButton* icm; + Gtk::CheckButton* gam; + + // 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_hotdeadpix_filt; + Gtk::CheckButton* raw_linenoise; + Gtk::CheckButton* raw_greenthresh; + Gtk::CheckButton* raw_dmethod; + 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; + + sigc::connection everythingConn, basicConn, detailConn, colorConn, lensConn, compositionConn, metaicmConn, rawConn; + + sigc::connection wbConn, exposureConn, shConn, pcvignetteConn, gradientConn, labcurveConn, colorappearanceConn; + sigc::connection sharpenConn, gradsharpenConn, microcontrastConn, impdenConn, dirpyrdenConn, waveqConn, defringeConn, epdConn, dirpyreqConn; + sigc::connection vibranceConn, chmixerConn, hsveqConn, rgbcurvesConn, chmixerbwConn; + 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; + sigc::connection raw_caredConn, raw_cablueConn, raw_ca_autocorrectConn, raw_hotdeadpix_filtConn, raw_linenoiseConn, raw_greenthreshConn, raw_ccStepsConn, raw_dmethodConn, 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 metaicmToggled (); + void rawToggled (); +}; + +#endif + diff --git a/rtgui/pcvignette.cc b/rtgui/pcvignette.cc new file mode 100644 index 000000000..6fb258b13 --- /dev/null +++ b/rtgui/pcvignette.cc @@ -0,0 +1,148 @@ +/* + * This file is part of RawTherapee. + */ +#include "pcvignette.h" +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +PCVignette::PCVignette () : Gtk::VBox(), FoldableToolPanel(this) +{ + set_border_width(4); + + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); + enabled->set_active (false); + enaConn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &PCVignette::enabledChanged) ); + + 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(*enabled); + pack_start(*Gtk::manage (new Gtk::HSeparator()), Gtk::PACK_EXPAND_WIDGET, 4); + 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); + enabled->set_inconsistent (!pedited->pcvignette.enabled); + } + + enaConn.block (true); + enabled->set_active (pp->pcvignette.enabled); + enaConn.block (false); + strength->setValue (pp->pcvignette.strength); + feather->setValue (pp->pcvignette.feather); + roundness->setValue (pp->pcvignette.roundness); + + lastEnabled = pp->pcvignette.enabled; + + 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 = enabled->get_active(); + + if (pedited) { + pedited->pcvignette.strength = strength->getEditedState (); + pedited->pcvignette.feather = feather->getEditedState (); + pedited->pcvignette.roundness = roundness->getEditedState (); + pedited->pcvignette.enabled = !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 && enabled->get_active()) { + 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 (batchMode) { + if (enabled->get_inconsistent()) { + enabled->set_inconsistent (false); + enaConn.block (true); + enabled->set_active (false); + enaConn.block (false); + } + else if (lastEnabled) + enabled->set_inconsistent (true); + + lastEnabled = enabled->get_active (); + } + if (listener) { + if (enabled->get_active()) + 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..cab1c568c --- /dev/null +++ b/rtgui/pcvignette.h @@ -0,0 +1,36 @@ +/* + * This file is part of RawTherapee. + */ +#ifndef _PCVIGNETTE_H_ +#define _PCVIGNETTE_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" + +class PCVignette : public Gtk::VBox, public AdjusterListener, public FoldableToolPanel { + + protected: + Gtk::CheckButton* enabled; + Adjuster* strength; + Adjuster* feather; + Adjuster* roundness; + bool lastEnabled; + sigc::connection enaConn; + + 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..2939ca248 --- /dev/null +++ b/rtgui/perspective.cc @@ -0,0 +1,110 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 () : Gtk::VBox(), FoldableToolPanel(this) { + + set_border_width(4); + + 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..48f33c882 --- /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 Gtk::VBox, 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..16c75623d --- /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, 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..9bb1ca126 --- /dev/null +++ b/rtgui/ppversion.h @@ -0,0 +1,31 @@ +#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 317 +#define PPVERSION_AEXP 301 //value of PPVERSION when auto exposure algorithm was modified + +/* + Log of version changes + 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 + addd 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..d6aaf8bc5 --- /dev/null +++ b/rtgui/preferences.cc @@ -0,0 +1,1756 @@ +/* + * 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" + +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); + + /* + * 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); + + 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_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); + + 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_EXPOSCORR_LABEL")); + appendBehavList (mi, M("TP_RAWEXPOS_LINEAR"), ADDSET_RAWEXPOS_LINEAR, false); + appendBehavList (mi, M("TP_RAWEXPOS_PRESER"), ADDSET_RAWEXPOS_PRESER, false); + appendBehavList (mi, M("TP_RAWEXPOS_BLACKS"), ADDSET_RAWEXPOS_BLACKS, false); + + 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); + + 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_spacing(4); + + Gtk::HBox* threadLimitHB = Gtk::manage( new Gtk::HBox () ); + threadLimitHB->set_border_width(4); + threadLimitHB->set_spacing(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, 0); + threadLimitHB->pack_end (*rgbDenoiseTreadLimitSB, Gtk::PACK_SHRINK, 0); + + mainContainer->pack_start(*threadLimitHB, 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)); + + monProfile = Gtk::manage (new Gtk::FileChooserButton (M("PREFERENCES_MONITORICC"), Gtk::FILE_CHOOSER_ACTION_OPEN)); + Gtk::Label* mplabel = Gtk::manage (new Gtk::Label (M("PREFERENCES_MONITORICC")+":", Gtk::ALIGN_LEFT)); + + cbAutoMonProfile = Gtk::manage (new Gtk::CheckButton (M("PREFERENCES_AUTOMONPROFILE"))); + autoMonProfileConn = cbAutoMonProfile->signal_toggled().connect (sigc::mem_fun(*this, &Preferences::autoMonProfileToggled)); + + 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); + colt->attach (*cbAutoMonProfile, 1, 2, 3, 4, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); +#endif + mvbcm->pack_start (*colt, Gtk::PACK_SHRINK, 4); + + autoMonProfileToggled(); + //Gtk::Frame* fdp = Gtk::manage (new Gtk::Frame (M("PREFERENCES_OUTPUTDEVICE"))); + 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::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* restartNeeded1 = Gtk::manage( new Gtk::Label (Glib::ustring(" (") + M("PREFERENCES_APPLNEXTSTARTUP") + ")") ); + Gtk::Label* restartNeeded2 = Gtk::manage( new Gtk::Label (Glib::ustring(" (") + M("PREFERENCES_APPLNEXTSTARTUP") + ")") ); + + Gtk::Table* colo = Gtk::manage (new Gtk::Table (2, 3)); + 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 (*restartNeeded1, 2, 3, 0, 1, Gtk::FILL, 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 (*restartNeeded2, 2, 3, 1, 2, Gtk::FILL, Gtk::SHRINK, 2, 2); + mvbcm->pack_start (*colo, Gtk::PACK_SHRINK, 4); + + Gtk::Label* cielab = Gtk::manage (new Gtk::Label (M("PREFERENCES_CIEART")+":", Gtk::ALIGN_LEFT)); + cbciecamfloat = Gtk::manage (new Gtk::CheckButton (M("PREFERENCES_CIEART_LABEL"))); + //autocielabConn = cbAutocielab->signal_toggled().connect (sigc::mem_fun(*this, &Preferences::autocielabToggled)); + Gtk::Table* coltcie = Gtk::manage (new Gtk::Table (1, 2)); + coltcie->attach (*cielab, 0, 1, 0, 1, Gtk::FILL, Gtk::SHRINK, 2, 2); + // coltcie->attach (*cbAutocielab, 1, 2, 0, 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); + //cbAutocielab->set_tooltip_markup (M("PREFERENCES_CIEART_TOOLTIP")); + coltcie->attach (*cbciecamfloat, 1, 2, 0, 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); + cbciecamfloat->set_tooltip_markup (M("PREFERENCES_CIEART_TOOLTIP")); + + mvbcm->pack_start (*coltcie, Gtk::PACK_SHRINK, 4); + // autocielabToggled(); + + 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::HBox* hbworkflow = Gtk::manage( new Gtk::HBox () ); + hbworkflow->set_border_width (4); + Gtk::Label* flayoutlab = Gtk::manage( new Gtk::Label (M("PREFERENCES_EDITORLAYOUT")+":") ); + editorLayout = Gtk::manage( new Gtk::ComboBoxText () ); + editorLayout->set_size_request(45, -1); + + 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, 4); + hbworkflow->pack_start (*editorLayout); + Gtk::Label* lNextStart = Gtk::manage( new Gtk::Label (Glib::ustring(" (") + M("PREFERENCES_APPLNEXTSTARTUP") + ")") ); + hbworkflow->pack_end (*lNextStart, Gtk::PACK_SHRINK, 4); + + Gtk::VBox* vbworkflow = Gtk::manage( new Gtk::VBox () ); + vbworkflow->pack_start (*hbworkflow, Gtk::PACK_SHRINK, 4); + + Gtk::HBox* hbworkflow2 = Gtk::manage( new Gtk::HBox () ); + ckbHistogramPositionLeft = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_HISTOGRAMPOSITIONLEFT")) ); + hbworkflow2->pack_start (*ckbHistogramPositionLeft, Gtk::PACK_SHRINK, 4); + ckbShowProfileSelector = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_SHOWPROFILESELECTOR")) ); + hbworkflow2->pack_start (*ckbShowProfileSelector, Gtk::PACK_SHRINK, 4); + ckbSquareDetailWindow = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_SQUAREDETAILWINDOW")) ); + hbworkflow2->pack_start (*ckbSquareDetailWindow, Gtk::PACK_SHRINK, 4); + vbworkflow->pack_start (*hbworkflow2, Gtk::PACK_SHRINK, 4); + + Gtk::HBox* hbworkflow3 = Gtk::manage( new Gtk::HBox () ); + ckbFileBrowserToolbarSingleRow = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_FILEBROWSERTOOLBARSINGLEROW")) ); + + hbworkflow3->pack_start (*ckbFileBrowserToolbarSingleRow, Gtk::PACK_SHRINK, 4); + vbworkflow->pack_start (*hbworkflow3, Gtk::PACK_SHRINK, 0); + + Gtk::HBox* hbworkflow4 = Gtk::manage( new Gtk::HBox () ); + + Gtk::Label* hb4label = Gtk::manage( new Gtk::Label (M("PREFERENCES_TP_LABEL")) ); + hbworkflow4->pack_start (*hb4label, Gtk::PACK_SHRINK, 4); + ckbHideTPVScrollbar = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_TP_VSCROLLBAR")) ); + hbworkflow4->pack_start (*ckbHideTPVScrollbar, Gtk::PACK_SHRINK, 4); + + ckbUseIconNoText = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_TP_USEICONORTEXT")) ); + hbworkflow4->pack_start (*ckbUseIconNoText, Gtk::PACK_SHRINK, 4); + + vbworkflow->pack_start (*hbworkflow4, Gtk::PACK_SHRINK, 4); + + fworklflow->add (*vbworkflow); + mvbsd->pack_start (*fworklflow, Gtk::PACK_SHRINK, 4); + + 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); + + hbUseSystemTheme->pack_start(*chUseSystemTheme, Gtk::PACK_SHRINK); + hbUseSystemTheme->pack_start (*useNextStart, Gtk::PACK_SHRINK, 0); + hbUseSystemTheme->pack_end (*butCropCol, Gtk::PACK_SHRINK, 0); + hbUseSystemTheme->pack_end (*cutOverlayLabel, 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->append_text (Glib::ustring("(")+M("PREFERENCES_GTKTHEME")+")"); + 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); + + slimUI = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_SLIMUI")) ); + vbftheme->pack_start(*slimUI, Gtk::PACK_SHRINK, 0); + + ftheme->add (*vbftheme); + mvbsd->pack_start (*ftheme, Gtk::PACK_SHRINK, 0); + +//----- + + Gtk::HBox* hbcd = Gtk::manage( new Gtk::HBox () ); + hbcd->set_spacing(4); + + Gtk::Frame* frl = Gtk::manage( new Gtk::Frame (M("PREFERENCES_CLIPPINGIND"))); + blinkClipped = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_BLINKCLIPPED")) ); + Gtk::VBox* vbrl = Gtk::manage( new Gtk::VBox () ); + vbrl->set_border_width(4); + vbrl->set_spacing (4); + vbrl->pack_start (*blinkClipped, Gtk::PACK_SHRINK, 0); + + 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::VBox* dfpfvb = Gtk::manage( new Gtk::VBox () ); + dfpfvb->set_spacing (4); + + Gtk::Frame* fdf = Gtk::manage( new Gtk::Frame (M("PREFERENCES_DATEFORMATFRAME")) ); + + Gtk::HBox* hb6 = Gtk::manage( new Gtk::HBox () ); + hb6->set_border_width (4); + hb6->set_spacing (4); + 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")); + hb6->pack_start (*dflab, Gtk::PACK_SHRINK, 0); + hb6->pack_end (*dateformat, Gtk::PACK_SHRINK, 0); + fdf->add (*hb6); + + dfpfvb->pack_start (*fdf, true, true, 0); + +//----- + Gtk::Frame* pff = Gtk::manage( new Gtk::Frame (M("PREFERENCES_PANFACTORFRAME")) ); + + Gtk::HBox* pfhb = Gtk::manage( new Gtk::HBox () ); + pfhb->set_border_width(4); + pfhb->set_spacing(4); + Gtk::Label* pfl = 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); + pfhb->pack_start (*pfl, Gtk::PACK_SHRINK, 0); + pfhb->pack_end (*panFactor, Gtk::PACK_SHRINK, 0); + pff->add (*pfhb); + + dfpfvb->pack_start (*pff, true, true, 0); + hbcd->pack_start (*dfpfvb, Gtk::PACK_SHRINK, 4); + mvbsd->pack_start (*hbcd, Gtk::PACK_SHRINK, 4); + + //----- + 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 () ); + overlayedFileNames = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_OVERLAY_FILENAMES")) ); + ckbInternalThumbIfUntouched = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_INTERNALTHUMBIFUNTOUCHED"))); + + vbro->set_border_width (4); + vbro->pack_start (*showDateTime, 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 (*ckbInternalThumbIfUntouched, Gtk::PACK_SHRINK, 0); + + 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, 8); + + Gtk::Label* lSndHelp = Gtk::manage (new Gtk::Label (M("PREFERENCES_SND_HELP"))); + pSnd->pack_start (*lSndHelp, 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, 12); + + 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, 12); + + 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::FileError& fe) { + 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.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.blinkClipped = blinkClipped->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; + + 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 (); + moptions.rtSettings.autoMonitorProfile = cbAutoMonProfile->get_active (); + 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.autocielab = cbAutocielab->get_active (); + moptions.rtSettings.ciecamfloat = cbciecamfloat->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.maxCacheEntries = (int)maxCacheEntries->get_value (); + moptions.overlayedFileNames = overlayedFileNames->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.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.histogramPosition = ckbHistogramPositionLeft->get_active() ? 1 : 2; + moptions.showProfileSelector = ckbShowProfileSelector->get_active(); + moptions.squareDetailWindow = ckbSquareDetailWindow->get_active(); + moptions.FileBrowserToolbarSingleRow = ckbFileBrowserToolbarSingleRow->get_active(); + moptions.hideTPVScrollbar = ckbHideTPVScrollbar->get_active(); + moptions.overwriteOutputFile = chOverwriteOutputFile->get_active (); + moptions.UseIconNoText = ckbUseIconNoText->get_active(); + + moptions.rgbDenoiseThreadLimit = rgbDenoiseTreadLimitSB->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); +#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); + cbAutoMonProfile->set_active(moptions.rtSettings.autoMonitorProfile); +#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); +// cbAutocielab->set_active (moptions.rtSettings.autocielab); + cbciecamfloat->set_active (moptions.rtSettings.ciecamfloat); + 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)); + + 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); + + blinkClipped->set_active (moptions.blinkClipped); + 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_filename (moptions.gimpDir); + if (safe_file_test (moptions.psDir, Glib::FILE_TEST_IS_DIR)) + psDir->set_filename (moptions.psDir); +#elif defined __APPLE__ + edPS->set_active (moptions.editorToSendTo==2); + if (safe_file_test (moptions.psDir, Glib::FILE_TEST_IS_DIR)) + psDir->set_filename (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); + maxCacheEntries->set_value (moptions.maxCacheEntries); + overlayedFileNames->set_active (moptions.overlayedFileNames); + 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); + + ckbHistogramPositionLeft->set_active(moptions.histogramPosition==1); + ckbShowProfileSelector->set_active(moptions.showProfileSelector); + ckbSquareDetailWindow->set_active(moptions.squareDetailWindow); + ckbFileBrowserToolbarSingleRow->set_active(moptions.FileBrowserToolbarSingleRow); + ckbHideTPVScrollbar->set_active(moptions.hideTPVScrollbar); + ckbUseIconNoText->set_active(moptions.UseIconNoText); + + rgbDenoiseTreadLimitSB->set_value(moptions.rgbDenoiseThreadLimit); + + //darkFrameDir->set_filename( moptions.rtSettings.darkFramesPath ); + //updateDFinfos(); + darkFrameDir->set_current_folder( moptions.rtSettings.darkFramesPath ); + darkFrameChanged (); + + //flatFieldDir->set_filename( moptions.rtSettings.flatFieldsPath ); + //updateFFinfos(); + flatFieldDir->set_current_folder( moptions.rtSettings.flatFieldsPath ); + flatFieldChanged (); + + 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) == 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 (); +} +*/ + +void Preferences::autoMonProfileToggled () { + monProfile->set_sensitive(!cbAutoMonProfile->get_active()); +} +/* +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 () { + + // set the initial theme back + if (theme->get_active_text () != options.theme) { + 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"); + 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->SetMainCurrent(); + if(moptions.tabbedUI) + parent->epanel->hide_all(); + else + parent->epanel->show_all(); + } + 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.histogramPosition != options.histogramPosition) { + // Update the position of the Histogram + parent->updateHistogramPosition(options.histogramPosition, moptions.histogramPosition); + } + if(moptions.showProfileSelector != options.showProfileSelector) { + // Update the position of the Profile selector + parent->updateTPProfileSelector(moptions.showProfileSelector); + } + +} + +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) == 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) == 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..587682d6b --- /dev/null +++ b/rtgui/preferences.h @@ -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 . + */ +#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::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* blinkClipped; + Gtk::SpinButton* hlThresh; + Gtk::SpinButton* shThresh; + + Gtk::SpinButton* panFactor; + + Gtk::ComboBoxText* intent; + Gtk::ComboBoxText* view; + Gtk::ComboBoxText* grey; + + Gtk::ComboBoxText* theme; + Gtk::CheckButton* slimUI; + Gtk::HBox* hbtheme; + Gtk::CheckButton* chUseSystemTheme; + Gtk::FontButton* fontbutton; + Gtk::ColorButton* butCropCol; + + Gtk::SpinButton* maxThumbSize; + Gtk::SpinButton* maxCacheEntries; + 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::SpinButton* rgbDenoiseTreadLimitSB; + + 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* ckbShowProfileSelector; + Gtk::CheckButton* ckbFileBrowserToolbarSingleRow; + Gtk::CheckButton* ckbHideTPVScrollbar; + Gtk::CheckButton* ckbSquareDetailWindow; + 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; + + 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..002a3d623 --- /dev/null +++ b/rtgui/preprocess.cc @@ -0,0 +1,153 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 () : Gtk::VBox(), FoldableToolPanel(this) +{ + set_border_width(4); + + hotDeadPixel = Gtk::manage(new Gtk::CheckButton((M("TP_PREPROCESS_HOTDEADPIXFILT")))); + hotDeadPixel->set_tooltip_markup (M("TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP")); + + 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); + + pack_start( *Gtk::manage (new Gtk::HSeparator())); + + pack_start( *hotDeadPixel, Gtk::PACK_SHRINK, 4); + + hdpixelconn = hotDeadPixel->signal_toggled().connect ( sigc::mem_fun(*this, &PreProcess::hotDeadPixelChanged), true); +} + +void PreProcess::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited) +{ + disableListener (); + hdpixelconn.block (true); + + if(pedited ){ + hotDeadPixel->set_inconsistent (!pedited->raw.hotDeadPixelFilter); + lineDenoise->setEditedState( pedited->raw.linenoise ? Edited : UnEdited ); + greenEqThreshold->setEditedState( pedited->raw.greenEq ? Edited : UnEdited ); + } + + lastHot = pp->raw.hotdeadpix_filt; + + hotDeadPixel->set_active (pp->raw.hotdeadpix_filt); + lineDenoise->setValue (pp->raw.linenoise); + greenEqThreshold->setValue (pp->raw.greenthresh); + + hdpixelconn.block (false); + enableListener (); +} + +void PreProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedited) +{ + pp->raw.hotdeadpix_filt = hotDeadPixel->get_active(); + pp->raw.linenoise = lineDenoise->getIntValue(); + pp->raw.greenthresh = greenEqThreshold->getIntValue(); + + if (pedited) { + pedited->raw.linenoise = lineDenoise->getEditedState (); + pedited->raw.greenEq= greenEqThreshold->getEditedState (); + pedited->raw.hotDeadPixelFilter = !hotDeadPixel->get_inconsistent(); + } +} + +void PreProcess::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 PreProcess::setBatchMode(bool batchMode) +{ + ToolPanel::setBatchMode (batchMode); + lineDenoise->showEditedCB (); + greenEqThreshold->showEditedCB (); +} + +void PreProcess::setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited) +{ + lineDenoise->setDefault( defParams->raw.linenoise); + greenEqThreshold->setDefault (defParams->raw.greenthresh); + + if (pedited) { + lineDenoise->setDefaultEditedState( pedited->raw.linenoise ? Edited : UnEdited); + greenEqThreshold->setDefaultEditedState(pedited->raw.greenEq ? Edited : UnEdited); + } else { + lineDenoise->setDefaultEditedState( Irrelevant ); + greenEqThreshold->setDefaultEditedState(Irrelevant ); + } +} + +void PreProcess::hotDeadPixelChanged () +{ + if (batchMode) { + if (hotDeadPixel->get_inconsistent()) { + hotDeadPixel->set_inconsistent (false); + hdpixelconn.block (true); + hotDeadPixel->set_active (false); + hdpixelconn.block (false); + } + else if (lastHot) + hotDeadPixel->set_inconsistent (true); + + lastHot = hotDeadPixel->get_active (); + } + if (listener) + listener->panelChanged (EvPreProcessHotDeadPixel, hotDeadPixel->get_active()?M("GENERAL_ENABLED"):M("GENERAL_DISABLED")); +} + +void PreProcess::setAdjusterBehavior (bool linedenoiseadd, bool greenequiladd) { + + lineDenoise->setAddMode(linedenoiseadd); + greenEqThreshold->setAddMode(greenequiladd); +} + +void PreProcess::trimValues (rtengine::procparams::ProcParams* pp) { + + lineDenoise->trimValue(pp->raw.linenoise); + greenEqThreshold->trimValue(pp->raw.greenthresh); +} diff --git a/rtgui/preprocess.h b/rtgui/preprocess.h new file mode 100644 index 000000000..fe6683a64 --- /dev/null +++ b/rtgui/preprocess.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 _PREPROCESS_H_ +#define _PREPROCESS_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" +#include "../rtengine/rawimage.h" + +class PreProcess : public Gtk::VBox, public AdjusterListener, public FoldableToolPanel { + + protected: + + Adjuster* lineDenoise; + + Adjuster* greenEqThreshold; + Gtk::CheckButton* hotDeadPixel; + bool lastHot; + sigc::connection hdpixelconn; + + 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 adjusterChanged (Adjuster* a, double newval); + void hotDeadPixelChanged(); + 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..68828cf5d --- /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)desiredW / previewImg->get_width(); + double zoom2 = (double)desiredH / 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_NEAREST); + 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 100644 index 000000000..3a1d2ea6b --- /dev/null +++ b/rtgui/previewloader.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 +#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_; + }; + + 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=int(omp_get_num_procs()*1.5); + #endif + + threadPool_=new Glib::ThreadPool(threadCount,0); + } + + Glib::ThreadPool* threadPool_; + MyMutex mutex_; + JobSet jobs_; + gint nConcurrentThreads; + + void processNextJob() + { + Job j; + { + 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()); + } + + 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 + try { + Thumbnail* tmb = 0; + { + if (safe_file_test(j.dir_entry_, Glib::FILE_TEST_EXISTS)) + { + tmb = cacheMgr->getEntry(j.dir_entry_); + } + } + + // we got something, so notify listener + if ( tmb ) + { + j.listener_->previewReady(j.dir_id_,new FileBrowserEntry(tmb,j.dir_entry_)); + } + } catch (Glib::Error &e){} catch(...){} + + 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..fafd6a563 --- /dev/null +++ b/rtgui/previewwindow.cc @@ -0,0 +1,205 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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), isMoving(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 + cropX*zoom; + y = imgY + cropY*zoom; + w = cropW * zoom; + h = cropH * zoom; + } +} + +void PreviewWindow::updatePreviewImage () { + + int W = get_width(), H = get_height(); + Glib::RefPtr wind = get_window(); + if( ! wind ) + 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()); + } + } +} + +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) + updatePreviewImage (); + + window->draw_drawable (get_style()->get_base_gc(Gtk::STATE_NORMAL), backBuffer, 0, 0, 0, 0, -1, -1); + + if (mainCropWin) { + Cairo::RefPtr cr = get_window()->create_cairo_context(); + int x, y, w, h; + getObservedFrameArea (x, y, w, h); + cr->set_source_rgb (1.0, 1.0, 1.0); + cr->set_line_width (3); + cr->rectangle (x-1.5, y-1.5, w+2, h+2); + cr->stroke (); + cr->set_source_rgb (1.0, 0.0, 0.0); + cr->set_line_width (1); + cr->rectangle (x-1.5, y-1.5, w+2, h+2); + 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; + + 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; + + 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..3562c85a3 --- /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; + int oldwidth, oldheight; + PreviewHandler* previewHandler; + sigc::connection rconn; + CropWindow* mainCropWin; + ImageArea* imageArea; + int imgX, imgY, imgW, imgH; + double zoom; + int press_x, press_y; + bool isMoving; + + 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..f6881bf45 --- /dev/null +++ b/rtgui/profilepanel.cc @@ -0,0 +1,673 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 (Gtk::FileChooserError &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 (Gtk::FileChooserError &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("PROFILEPANEL_FILEDLGFILTERPP")); + filter_pp.add_pattern("*"+paramFileExtension); + dialog.add_filter(filter_pp); + + Gtk::FileFilter filter_any; + filter_any.set_name(M("PROFILEPANEL_FILEDLGFILTERANY")); + 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 (profiles->getSelectedEntry()) : 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 (Gtk::FileChooserError &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 (Gtk::FileChooserError &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("PROFILEPANEL_FILEDLGFILTERPP")); + filter_pp.add_pattern("*"+paramFileExtension); + dialog.add_filter(filter_pp); + + Gtk::FileFilter filter_any; + filter_any.set_name(M("PROFILEPANEL_FILEDLGFILTERANY")); + 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); + custom->set(true); + customCreated = true; + } + else if (fillMode->get_active()) + custom->pparams->setDefaults(); + + int err = custom->load (fname); + if (!err) { + bool prevState = changeconn.block(true); + Gtk::TreeIter newEntry = addCustomRow(); + profiles->set_active (newEntry); + currRow = profiles->get_active(); + changeconn.block(prevState); + + if (event->state & Gdk::CONTROL_MASK) { + // applying partial profile + PartialProfile ppTemp(true); + // the 2 next line modify custom->pedited without modifying custom->pparams + partialProfileDlg->applyPaste (ppTemp.pparams, ppTemp.pedited, custom->pparams, custom->pedited); + if (fillMode->get_active()) + *custom->pparams = *ppTemp.pparams; + *custom->pedited = *ppTemp.pedited; + ppTemp.deleteInstance(); + } + if (fillMode->get_active()) + custom->pedited->set(true); + + 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); + custom->pedited->set(true); + profiles->set_active (addCustomRow()); + currRow = profiles->get_active(); + } + else { + profiles->set_active(getCustomRow()); + currRow = profiles->get_active(); + } + + ProcParams pp = clipboard.getProcParams (); + *custom->pparams = pp; + + changeconn.block(prevState); + + if (event->state & Gdk::CONTROL_MASK) { + // applying partial profile + PartialProfile ppTemp(true); + // the 2 next line modify custom->pedited without modifying custom->pparams + partialProfileDlg->applyPaste (ppTemp.pparams, ppTemp.pedited, custom->pparams, custom->pedited); + *custom->pedited = *ppTemp.pedited; + ppTemp.deleteInstance(); + } + + 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; + pe.set(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(); + pe->set(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..6541e10ba --- /dev/null +++ b/rtgui/profilestore.cc @@ -0,0 +1,690 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 () { + + // 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/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..cb5f5c227 --- /dev/null +++ b/rtgui/rawcacorrection.cc @@ -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 . + */ +#include "rawcacorrection.h" +#include "guiutils.h" +#include "../rtengine/safegtk.h" +#include +#include "rtimage.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +RAWCACorr::RAWCACorr () : Gtk::VBox(), FoldableToolPanel(this) +{ + set_border_width(4); + + 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..5cf28f200 --- /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 Gtk::VBox, 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..719146517 --- /dev/null +++ b/rtgui/rawexposure.cc @@ -0,0 +1,233 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 () : Gtk::VBox(), FoldableToolPanel(this) +{ + set_border_width(4); + + 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(); + PexBlackone = Gtk::manage(new Adjuster (M("TP_RAWEXPOS_BLACKONE"),-2048,2048,0.1,0));//black level + PexBlackone->setAdjusterListener (this); + if (PexBlackone->delay < 1000) PexBlackone->delay = 1000; + PexBlackone->show(); + PexBlacktwo = Gtk::manage(new Adjuster (M("TP_RAWEXPOS_BLACKTWO"),-2048,2048,0.1,0));//black level + PexBlacktwo->setAdjusterListener (this); + if (PexBlacktwo->delay < 1000) PexBlacktwo->delay = 1000; + PexBlacktwo->show(); + PexBlackthree = Gtk::manage(new Adjuster (M("TP_RAWEXPOS_BLACKTHREE"),-2048,2048,0.1,0));//black level + PexBlackthree->setAdjusterListener (this); + if (PexBlackthree->delay < 1000) PexBlackthree->delay = 1000; + PexBlackthree->show(); + PexBlackzero = Gtk::manage(new Adjuster (M("TP_RAWEXPOS_BLACKZERO"),-2048,2048,0.1,0));//black level + PexBlackzero->setAdjusterListener (this); + if (PexBlackzero->delay < 1000) PexBlackzero->delay = 1000; + PexBlackzero->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, &RAWExposure::GreenChanged)); + + + + pack_start( *PexPos, Gtk::PACK_SHRINK, 4);//exposi + pack_start( *PexPreser, Gtk::PACK_SHRINK, 4); + pack_start( *PexBlackone, Gtk::PACK_SHRINK, 4);//black + pack_start( *PexBlackzero, Gtk::PACK_SHRINK, 4);//black + pack_start( *PexBlacktwo, Gtk::PACK_SHRINK, 4);//black + pack_start( *PexBlackthree, Gtk::PACK_SHRINK, 4);//black + pack_start( *PextwoGreen, Gtk::PACK_SHRINK, 4);//black 2 green + +} + +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 ); + PexBlackzero->setEditedState( pedited->raw.exBlackzero ? Edited : UnEdited ); + PexBlackone->setEditedState( pedited->raw.exBlackone ? Edited : UnEdited ); + PexBlacktwo->setEditedState( pedited->raw.exBlacktwo ? Edited : UnEdited ); + PexBlackthree->setEditedState( pedited->raw.exBlackthree ? Edited : UnEdited ); + + } + greenconn.block (true); + PextwoGreen->set_active (pp->raw.twogreen); + greenconn.block (false); + lastPextwoGreen = pp->raw.twogreen; + + + PexPos->setValue (pp->raw.expos); + PexPreser->setValue (pp->raw.preser);//exposi + PexBlackzero->setValue (pp->raw.blackzero);//black + PexBlackone->setValue (pp->raw.blackone);//black + PexBlacktwo->setValue (pp->raw.blacktwo);//black + + if(!PextwoGreen->get_active())PexBlackthree->setValue (pp->raw.blackthree);else PexBlackthree->setValue (PexBlackzero->getValue()); + + enableListener (); +} + +void RAWExposure::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedited) +{ + pp->raw.expos = PexPos->getValue(); + pp->raw.preser = PexPreser->getValue();//exposi + pp->raw.blackzero = PexBlackzero->getValue();// black + pp->raw.blackone = PexBlackone->getValue();// black + pp->raw.blacktwo = PexBlacktwo->getValue();// black + pp->raw.twogreen=PextwoGreen->get_active(); + if(PextwoGreen->get_active()){pp->raw.blackthree=pp->raw.blackzero;} else {pp->raw.blackthree = PexBlackthree->getValue();}// active or desactive 2 green together + + + if (pedited) { + pedited->raw.exPos = PexPos->getEditedState (); + pedited->raw.exPreser = PexPreser->getEditedState ();//exposi + pedited->raw.exBlackzero = PexBlackzero->getEditedState ();//black + pedited->raw.exBlackone = PexBlackone->getEditedState ();//black + pedited->raw.exBlacktwo = PexBlacktwo->getEditedState ();//black + pedited->raw.exBlackthree = PexBlackthree->getEditedState ();//black + pedited->raw.exTwoGreen =!PextwoGreen->get_inconsistent(); + + + } + +} + +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 ); + else if (a == PexBlackzero) {if(!PextwoGreen->get_active()) + listener->panelChanged (EvPreProcessExpBlackzero, value ); else {listener->panelChanged (EvPreProcessExpBlackzero, value );PexBlackthree->setValue (PexBlackzero->getValue());}} + else if (a == PexBlackone) + listener->panelChanged (EvPreProcessExpBlackone, value ); + else if (a == PexBlacktwo) + listener->panelChanged (EvPreProcessExpBlacktwo, value ); + else if (a == PexBlackthree) {if(!PextwoGreen->get_active()) + listener->panelChanged (EvPreProcessExpBlackthree, value ); else {listener->panelChanged (EvPreProcessExpBlackthree, value );PexBlackzero->setValue (PexBlackthree->getValue());}} + } + + } +} +void RAWExposure::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")); + PexBlackthree->setValue (PexBlackzero->getValue());//two green together + } + + else + { listener->panelChanged (EvPreProcessExptwoGreen, M("GENERAL_DISABLED")); + } + + } + +} + +void RAWExposure::setBatchMode(bool batchMode) +{ + ToolPanel::setBatchMode (batchMode); + PexPos->showEditedCB (); + PexPreser->showEditedCB ();//exposure + PexBlackzero->showEditedCB ();//black + PexBlackone->showEditedCB ();//black + PexBlacktwo->showEditedCB ();//black + PexBlackthree->showEditedCB ();//black + +} + +void RAWExposure::setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited) +{ + PexPos->setDefault( defParams->raw.expos); + PexPreser->setDefault( defParams->raw.preser); + PexBlackzero->setDefault( defParams->raw.blackzero); + PexBlackone->setDefault( defParams->raw.blackone); + PexBlacktwo->setDefault( defParams->raw.blacktwo); + PexBlackthree->setDefault( defParams->raw.blackthree); + + if (pedited) { + PexPos->setDefaultEditedState( pedited->raw.exPos ? Edited : UnEdited); + PexPreser->setDefaultEditedState( pedited->raw.exPreser ? Edited : UnEdited); + PexBlackzero->setDefaultEditedState( pedited->raw.exBlackzero ? Edited : UnEdited); + PexBlackone->setDefaultEditedState( pedited->raw.exBlackone ? Edited : UnEdited); + PexBlacktwo->setDefaultEditedState( pedited->raw.exBlacktwo ? Edited : UnEdited); + PexBlackthree->setDefaultEditedState( pedited->raw.exBlackthree ? Edited : UnEdited); + + } else { + PexPos->setDefaultEditedState( Irrelevant ); + PexPreser->setDefaultEditedState( Irrelevant ); + PexBlackzero->setDefaultEditedState( Irrelevant ); + PexBlackone->setDefaultEditedState( Irrelevant ); + PexBlacktwo->setDefaultEditedState( Irrelevant ); + PexBlackthree->setDefaultEditedState( Irrelevant ); + + } +} + +void RAWExposure::setAdjusterBehavior (bool pexposadd, bool pexpreseradd, bool pexblackadd) { + + PexPos->setAddMode(pexposadd); + PexPreser->setAddMode(pexpreseradd); + PexBlackzero->setAddMode(pexblackadd); + PexBlackone->setAddMode(pexblackadd); + PexBlacktwo->setAddMode(pexblackadd); + PexBlackthree->setAddMode(pexblackadd); +} + +void RAWExposure::trimValues (rtengine::procparams::ProcParams* pp) { + + PexPos->trimValue(pp->raw.expos); + PexPreser->trimValue(pp->raw.preser); + PexBlackzero->trimValue(pp->raw.blackzero); + PexBlackone->trimValue(pp->raw.blackone); + PexBlacktwo->trimValue(pp->raw.blacktwo); + PexBlackthree->trimValue(pp->raw.blackthree); +} diff --git a/rtgui/rawexposure.h b/rtgui/rawexposure.h new file mode 100644 index 000000000..c65bfe4c1 --- /dev/null +++ b/rtgui/rawexposure.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 _RAWEXPOSURE_H_ +#define _RAWEXPOSURE_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" +#include "../rtengine/rawimage.h" + +class RAWExposure : public Gtk::VBox, public AdjusterListener, public FoldableToolPanel { + +protected: + Adjuster* PexPos; + Adjuster* PexPreser; + Adjuster* PexBlackzero; + Adjuster* PexBlackone; + Adjuster* PexBlacktwo; + Adjuster* PexBlackthree; + bool lastPextwoGreen; + sigc::connection greenconn; + Gtk::CheckButton* PextwoGreen; + +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 GreenChanged() ; + void adjusterChanged (Adjuster* a, double newval); + void setAdjusterBehavior (bool pexposadd, bool pexpreseradd, bool pexblackadd); + void trimValues (rtengine::procparams::ProcParams* pp); +}; + +#endif diff --git a/rtgui/rawprocess.cc b/rtgui/rawprocess.cc new file mode 100644 index 000000000..0fbc3a3d2 --- /dev/null +++ b/rtgui/rawprocess.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 "rawprocess.h" +#include "options.h" +#include "guiutils.h" +using namespace rtengine; +using namespace rtengine::procparams; + +RawProcess::RawProcess () : Gtk::VBox(), FoldableToolPanel(this) +{ + set_border_width(4); + + 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); + 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=""; + if( curSelection>=0 && curSelection < procparams::RAWParams::numMethods) + methodName = procparams::RAWParams::methodstring[curSelection]; + + if (listener) + listener->panelChanged (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..4de09de9c --- /dev/null +++ b/rtgui/rawprocess.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 . + */ +#ifndef _RAWPROCESS_H_ +#define _RAWPROCESS_H_ + +#include +#include "adjuster.h" +#include "guiutils.h" +#include "toolpanel.h" + + +class RawProcess : public Gtk::VBox, 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; + //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..e8ee0afca --- /dev/null +++ b/rtgui/recentbrowser.cc @@ -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 . + */ +#include "recentbrowser.h" +#include "multilangmgr.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); + + 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) { + + conn.block (true); + + recentDirs->remove_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..a53883ea7 --- /dev/null +++ b/rtgui/renamedlg.cc @@ -0,0 +1,216 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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); + + 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); + all = add_button ("All", RESPONSE_ALL); + + newName->set_activates_default (true); + set_default_response (Gtk::RESPONSE_OK); + + 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); + 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..6819b6ebf --- /dev/null +++ b/rtgui/resize.cc @@ -0,0 +1,576 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 +#include "guiutils.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +Resize::Resize () : Gtk::VBox(), FoldableToolPanel(this), maxw(100000), maxh(100000) { + + set_border_width(4); + + cropw = 0; + croph = 0; + + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); + pack_start(*enabled); + pack_start(*Gtk::manage (new Gtk::HSeparator()), Gtk::PACK_SHRINK, 2); + + Gtk::Table* combos = Gtk::manage (new Gtk::Table (2, 2)); + + appliesTo = Gtk::manage (new MyComboBoxText ()); + appliesTo->append_text (M("TP_RESIZE_CROPPEDAREA")); + appliesTo->append_text (M("TP_RESIZE_FULLIMAGE")); + appliesTo->set_active (0); + + combos->attach (*Gtk::manage (new Gtk::Label (M("TP_RESIZE_APPLIESTO"))), 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); + + method = Gtk::manage (new MyComboBoxText ()); + method->append_text (M("TP_RESIZE_NEAREST")); + method->append_text (M("TP_RESIZE_BILINEAR")); + method->append_text (M("TP_RESIZE_BICUBIC")); + method->append_text (M("TP_RESIZE_BICUBICSF")); + method->append_text (M("TP_RESIZE_BICUBICSH")); + method->append_text (M("TP_RESIZE_LANCZOS")); + method->set_active (0); + + combos->attach (*Gtk::manage (new Gtk::Label (M("TP_RESIZE_METHOD"))), 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); + + combos->attach (*Gtk::manage (new Gtk::Label (M("TP_RESIZE_SPECIFY"))), 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->pack_start (*Gtk::manage (new Gtk::Label (M("TP_RESIZE_W"))), Gtk::PACK_SHRINK, 4); + wbox->pack_start (*w); + hbox->pack_start (*Gtk::manage (new Gtk::Label (M("TP_RESIZE_H"))), Gtk::PACK_SHRINK, 4); + hbox->pack_start (*h); + sbox->pack_start (*wbox); + sbox->pack_start (*hbox); + + sizeBox->pack_start (*sbox, Gtk::PACK_SHRINK, 4); + 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) ); + enaConn = enabled->signal_toggled().connect ( sigc::mem_fun(*this, &Resize::enabledToggled) ); + + 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); + enabled->set_active (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); + + method->set_active (2); + if (pp->resize.method == "Nearest") + method->set_active (0); + else if (pp->resize.method == "Bilinear") + method->set_active (1); + else if (pp->resize.method == "Bicubic") + method->set_active (2); + else if (pp->resize.method == "Bicubic (Softer)") + method->set_active (3); + else if (pp->resize.method == "Bicubic (Sharper)") + method->set_active (4); + else if (pp->resize.method == "Lanczos") + method->set_active (5); + else if (pp->resize.method == "Downscale (Better)" || + pp->resize.method == "Downscale (Faster)") + { + method->set_active (5); + } + + 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 (8); + if (!pedited->resize.dataspec) + spec->set_active (4); + enabled->set_inconsistent (!pedited->resize.enabled); + } + + lastEnabled = pp->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 = "Bicubic"; + if (method->get_active_row_number() == 0) + pp->resize.method = "Nearest"; + else if (method->get_active_row_number() == 1) + pp->resize.method = "Bilinear"; + else if (method->get_active_row_number() == 2) + pp->resize.method = "Bicubic"; + else if (method->get_active_row_number() == 3) + pp->resize.method = "Bicubic (Softer)"; + else if (method->get_active_row_number() == 4) + pp->resize.method = "Bicubic (Sharper)"; + else if (method->get_active_row_number() == 5) + pp->resize.method = "Lanczos"; + + pp->resize.dataspec = dataSpec; + pp->resize.width = w->get_value_as_int (); + pp->resize.height = h->get_value_as_int (); + pp->resize.enabled = enabled->get_active (); + //printf(" L:%d H:%d\n", pp->resize.width, pp->resize.height); + + if (pedited) { + pedited->resize.enabled = !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() != 8; + 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 && (enabled->get_active () || 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 && (enabled->get_active () || batchMode)) { + //printf("Appel du listener\n"); + listener->panelChanged (EvResizeAppliesTo, appliesTo->get_active_text()); + } +} + +void Resize::methodChanged () { + + if (listener && (enabled->get_active () || batchMode)) + listener->panelChanged (EvResizeMethod, method->get_active_text()); +} + +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; + } + 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 (enabled->get_active () || 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 (enabled->get_active () || 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 && (enabled->get_active () || 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::enabledToggled () { + + if (batchMode) { + if (enabled->get_inconsistent()) { + enabled->set_inconsistent (false); + enaConn.block (true); + enabled->set_active (false); + enaConn.block (false); + } + else if (lastEnabled) + enabled->set_inconsistent (true); + + lastEnabled = enabled->get_active (); + } + + if (listener) { + if (enabled->get_active ()) + 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..0af6e8631 --- /dev/null +++ b/rtgui/resize.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 _RESIZE_H_ +#define _RESIZE_H_ + +#include +#include "adjuster.h" +#include "guiutils.h" +#include "toolpanel.h" +#include "guiutils.h" + +class Resize : public Gtk::VBox, public AdjusterListener, public FoldableToolPanel, public rtengine::SizeListener { + + protected: + Gtk::CheckButton* enabled; + 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, enaConn; + bool wDirty, hDirty, lastEnabled; + + public: + + Resize (); + ~Resize (); + + 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 enabledToggled (); + + 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..07c169ab5 --- /dev/null +++ b/rtgui/rgbcurves.cc @@ -0,0 +1,174 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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" +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +RGBCurves::RGBCurves () : Gtk::VBox(), FoldableToolPanel(this) { + + set_border_width(4); + + 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"))); + 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->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->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::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..e3a3d4218 --- /dev/null +++ b/rtgui/rgbcurves.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 _RGBCURVES_H_ +#define _RGBCURVES_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" +#include "curveeditor.h" +#include "curveeditorgroup.h" +#include "colorprovider.h" + +class RGBCurves : public Gtk::VBox, 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 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..dd478cdaa --- /dev/null +++ b/rtgui/rotate.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 "rotate.h" +#include +#include "guiutils.h" +#include "rtimage.h" + +extern Glib::ustring argv0; + +using namespace rtengine; +using namespace rtengine::procparams; + +Rotate::Rotate () : Gtk::VBox(), FoldableToolPanel(this) { + + set_border_width(4); + + 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..938710ed0 --- /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 Gtk::VBox, 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..f90eb397a --- /dev/null +++ b/rtgui/rtimage.cc @@ -0,0 +1,146 @@ +/* + * 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" +#include "../rtengine/safekeyfile.h" + +extern Glib::ustring argv0; +extern Options options; + +std::vector imagesPaths; +std::vector imagesList; // List of images in order to live update them on theme switch + +/* + * 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 path; + if (rtlFileName.length()) { + const Gtk::TextDirection dir = get_direction(); + if (dir == Gtk::TEXT_DIR_RTL) + path = findIconAbsolutePath(rtlFileName); + else + path = findIconAbsolutePath(fileName); + } + else + path = findIconAbsolutePath(fileName); + + set(path); + imagesList.push_back(this); +} + +RTImage::~RTImage() { + // Remove the image from the global images list + std::vector::iterator i = std::find (imagesList.begin(), imagesList.end(), this); + if (i!=imagesList.end()) + imagesList.erase(i); +} + +void RTImage::updateImages() { + for (unsigned int i=0; iproperty_file(); + Glib::ustring fileName = Glib::path_get_basename(oldPath); + imagesList[i]->clear(); + Glib::ustring fullPath = findIconAbsolutePath(fileName); + imagesList[i]->set(fullPath); + } +} + +// 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(); + Glib::ustring fullPath = findIconAbsolutePath(newImage); + set(fullPath); +} + +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 = ""); + ~RTImage(); + 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..cf3b31f9a --- /dev/null +++ b/rtgui/rtwindow.cc @@ -0,0 +1,731 @@ +/* + * 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) +,epanel(NULL) +,fpanel(NULL) +,btn_fullscreen(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 + set_title("RawTherapee "+versionString); + property_allow_shrink() = true; + set_default_size(options.windowWidth, options.windowHeight); + set_modal(false); + set_resizable(true); + if (options.windowMaximized) + maximize(); + else + unmaximize(); + + 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 () ); + 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 +} + +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)) { + // Fullscreen mode + options.windowMaximized = true; + } + return true; +} + +void RTWindow::on_mainNB_switch_page(GtkNotebookPage* page, guint page_num) { + if (page_num > 1) { + if (isSingleTabMode()) MoveFileBrowserToEditor(); + + EditorPanel *ep = static_cast(mainNB->get_nth_page(page_num)); + ep->setAspect(); + } 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 (page_num==0) + MoveFileBrowserToMain(); + } + } +} + +void RTWindow::addEditorPanel (EditorPanel* ep, const std::string &name) { + if (EditWindow::isMultiDisplayEnabled()) { + EditWindow * wndEdit = EditWindow::getInstance(this); + wndEdit->show_all(); + 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 (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); + + 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 (EditWindow::isMultiDisplayEnabled()) { + EditWindow * wndEdit = EditWindow::getInstance(this); + wndEdit->remEditorPanel(ep); + } else { + epanels.erase (ep->getShortName()); + filesEdited.erase (ep->getShortName ()); + fpanel->refreshEditedState (filesEdited); + + mainNB->remove_page (*ep); + + if (mainNB->get_current_page () == mainNB->page_num (*bpanel)) + mainNB->set_current_page (mainNB->page_num (*fpanel)); + // TODO: ask what to do: close & apply, close & apply selection, close & revert, cancel + } +} + +bool RTWindow::selectEditorPanel(const std::string &name) { + if (EditWindow::isMultiDisplayEnabled()) { + EditWindow * wndEdit = EditWindow::getInstance(this); + if (wndEdit->selectEditorPanel(name)) return true; + } else { + std::map::iterator iep = epanels.find(name); + + if (iep!=epanels.end()) { + mainNB->set_current_page (mainNB->page_num (*iep->second)); + return true; + } + } + + 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(); + + // First and second are file browser and batch queue + if (pageCount>2) { + for (int i=2;i(mainNB->get_nth_page(i)))->getIsProcessing(); + } + } + + if (isProcessing) return true; + + + if( fpanel ) + fpanel->saveOptions (); + if( bpanel ) + bpanel->saveOptions (); + + if (isSingleTabMode() || simpleEditor) { + 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(); + } + + 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); + epanel->catalogPane->add(*fCatalog); + fCatalog->enableTabMode(true); + fCatalog->refreshHeight(); + fCatalog->tbLeftPanel_1_visible(false); + fCatalog->tbRightPanel_1_visible(false); + } +} + +void RTWindow::updateTPProfileSelector (bool showMe) { + epanel->updateProfileSelector (showMe); + + std::map::const_iterator itr; + for(itr = epanels.begin(); itr != epanels.end(); ++itr){ + ((*itr).second)->updateProfileSelector (showMe); + } +} + +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::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; +} diff --git a/rtgui/rtwindow.h b/rtgui/rtwindow.h new file mode 100644 index 000000000..54fbdedca --- /dev/null +++ b/rtgui/rtwindow.h @@ -0,0 +1,104 @@ +/* + * 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 && !EditWindow::isMultiDisplayEnabled(); }; + 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); +#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 updateTPProfileSelector (bool showMe); + void updateHistogramPosition (int oldPosition, int newPosition); + void updateTabsUsesIcons (bool useIcons); + void updateFBQueryTB (bool singleRow); + bool getIsFullscreen() { return is_fullscreen; } +}; + +#endif diff --git a/rtgui/saveasdlg.cc b/rtgui/saveasdlg.cc new file mode 100644 index 000000000..e056fad10 --- /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 (Gtk::FileChooserError &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/shadowshighlights.cc b/rtgui/shadowshighlights.cc new file mode 100644 index 000000000..3306c7023 --- /dev/null +++ b/rtgui/shadowshighlights.cc @@ -0,0 +1,248 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 () : Gtk::VBox(), FoldableToolPanel(this) { + + set_border_width(4); + + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); + enabled->set_active (false); + pack_start (*enabled); + enaConn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &ShadowsHighlights::enabledChanged) ); + + pack_start (*Gtk::manage (new Gtk::HSeparator())); + + 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); + enabled->set_inconsistent (!pedited->sh.enabled); + hq->set_inconsistent (!pedited->sh.hq); + } + + enaConn.block (true); + enabled->set_active (pp->sh.enabled); + enaConn.block (false); + hqConn.block (true); + hq->set_active (pp->sh.hq); + hqConn.block (false); + + lastEnabled = pp->sh.enabled; + 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 = enabled->get_active(); + 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 = !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 && enabled->get_active()) { + + 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 (batchMode) { + if (enabled->get_inconsistent()) { + enabled->set_inconsistent (false); + enaConn.block (true); + enabled->set_active (false); + enaConn.block (false); + } + else if (lastEnabled) + enabled->set_inconsistent (true); + + lastEnabled = enabled->get_active (); + } + + if (listener) { + if (enabled->get_active()) + 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..12acae2b6 --- /dev/null +++ b/rtgui/shadowshighlights.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 _SHADOWSHIGHLIGHTS_H_ +#define _SHADOWSHIGHLIGHTS_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" + +class ShadowsHighlights : public Gtk::VBox, public AdjusterListener, public FoldableToolPanel { + + protected: + Adjuster* highlights; + Adjuster* h_tonalwidth; + Adjuster* shadows; + Adjuster* s_tonalwidth; + Adjuster* lcontrast; + Adjuster* radius; + Gtk::CheckButton* enabled; + Gtk::CheckButton* hq; + bool lastEnabled, lastHQ; + sigc::connection enaConn, 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..0ab5fac1f --- /dev/null +++ b/rtgui/sharpenedge.cc @@ -0,0 +1,189 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 +#include + +using namespace rtengine; +using namespace rtengine::procparams; + + +SharpenEdge::SharpenEdge () : Gtk::VBox(), FoldableToolPanel(this) { + + set_border_width(4); + + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); + enabled->set_active (true); + pack_start(*enabled, Gtk::PACK_SHRINK, 0); + + Gtk::HSeparator *hsep1 = Gtk::manage (new Gtk::HSeparator()); + hsep1->show (); + pack_start (*hsep1); + + 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 (); + + enaconn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &SharpenEdge::enabled_toggled) ); + 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); + enabled->set_inconsistent (!pedited->sharpenEdge.enabled); + threechannels->set_inconsistent (!pedited->sharpenEdge.threechannels); + } + enaconn.block (true); + enabled->set_active (pp->sharpenEdge.enabled); + enaconn.block (false); + lastEnabled = 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 = enabled->get_active (); + pp->sharpenEdge.passes = (int)passes->getValue(); + pp->sharpenEdge.amount = amount->getValue (); + pp->sharpenEdge.threechannels = threechannels->get_active (); + + if (pedited) { + pedited->sharpenEdge.enabled = !enabled->get_inconsistent(); + pedited->sharpenEdge.passes = passes->getEditedState (); + pedited->sharpenEdge.amount = amount->getEditedState (); + pedited->sharpenEdge.threechannels = !threechannels->get_inconsistent(); + } + +} + +void SharpenEdge::enabled_toggled () { + + if (batchMode) { + if (enabled->get_inconsistent()) { + enabled->set_inconsistent (false); + enaconn.block (true); + enabled->set_active (false); + enaconn.block (false); + } + else if (lastEnabled) + enabled->set_inconsistent (true); + + lastEnabled = enabled->get_active (); + } + + if (listener) { + if (enabled->get_active ()) + listener->panelChanged (EvSharpenEdgeEnabled, M("GENERAL_ENABLED")); + //listener->panelChanged (EvMLunifor, 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 && enabled->get_active ()) { + 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 && enabled->get_active()) { + 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..83b63e288 --- /dev/null +++ b/rtgui/sharpenedge.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 . + * + * + * Manuel Llorens' algorithm of edge sharpening + * + * + */ +#ifndef _SHARPENEDGE_H_ +#define _SHARPENEDGE_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" + +class SharpenEdge : public Gtk::VBox, public AdjusterListener, public FoldableToolPanel { + +protected: + + Gtk::CheckButton* enabled; + Adjuster* passes; + Adjuster* amount; + Gtk::CheckButton* threechannels; + + bool lastEnabled; + sigc::connection enaconn; + 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 enabled_toggled (); + void chanthree_toggled (); + +}; + +#endif diff --git a/rtgui/sharpening.cc b/rtgui/sharpening.cc new file mode 100644 index 000000000..4dd87a2cf --- /dev/null +++ b/rtgui/sharpening.cc @@ -0,0 +1,480 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 () : Gtk::VBox(), FoldableToolPanel(this) { + + set_border_width(4); + + 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) ); + + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); + enabled->set_tooltip_markup (M("TP_SHARPENING_TOOLTIP")); + + enabled->set_active (true); + pack_start(*enabled); + enabled->show (); + Gtk::HSeparator *hsep6aa = Gtk::manage (new Gtk::HSeparator()); + pack_start(*hsep6aa, Gtk::PACK_SHRINK, 2); + hsep6aa->show (); + + 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); + threshold->setAdjusterListener (this); + eradius->setAdjusterListener (this); + etolerance->setAdjusterListener (this); + hcamount->setAdjusterListener (this); + + edgebox->reference (); + hcbox->reference (); + usm->reference (); + rld->reference (); + + enaConn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &Sharpening::enabled_toggled) ); + 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); + + enabled->set_inconsistent (multiImage && !pedited->sharpening.enabled); + halocontrol->set_inconsistent (multiImage && !pedited->sharpening.halocontrol); + edgesonly->set_inconsistent (multiImage && !pedited->sharpening.edgesonly); + } + + enaConn.block (true); + enabled->set_active (pp->sharpening.enabled); + enaConn.block (false); + lastEnabled = 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 = enabled->get_active (); + 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 = !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||enabled->get_active()) ) { + + 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||enabled->get_active()) ) { + listener->panelChanged (EvShrThresh, threshold->getHistoryString()); + } +} + +void Sharpening::enabled_toggled () { + + if (multiImage) { + if (enabled->get_inconsistent()) { + enabled->set_inconsistent (false); + enaConn.block (true); + enabled->set_active (false); + enaConn.block (false); + } + else if (lastEnabled) + enabled->set_inconsistent (true); + + lastEnabled = enabled->get_active (); + } + + if (listener) { + if (enabled->get_inconsistent()) + listener->panelChanged (EvShrEnabled, M("GENERAL_UNCHANGED")); + else if (enabled->get_active ()) + 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||enabled->get_active()) ) { + 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||enabled->get_active()) ) { + 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||enabled->get_active()) ) + 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..1f87af11f --- /dev/null +++ b/rtgui/sharpening.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 _SHARPENING_H_ +#define _SHARPENING_H_ + +#include +#include "adjuster.h" +#include "thresholdadjuster.h" +#include "toolpanel.h" + +class Sharpening : public Gtk::VBox, 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* enabled; + bool lastEnabled; + sigc::connection enaConn; + 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 enabled_toggled (); + 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..7d20822e4 --- /dev/null +++ b/rtgui/sharpenmicro.cc @@ -0,0 +1,188 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 +#include + +using namespace rtengine; +using namespace rtengine::procparams; + + +SharpenMicro::SharpenMicro () : Gtk::VBox(), FoldableToolPanel(this) { + + set_border_width(4); + + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); + enabled->set_active (true); + enabled->set_tooltip_markup (M("TP_SHARPENING_TOOLTIP")); + + pack_start(*enabled, Gtk::PACK_SHRINK, 0); + enabled->show (); + + Gtk::HSeparator *hsep1 = Gtk::manage (new Gtk::HSeparator()); + hsep1->show (); + pack_start (*hsep1); + + 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 (); + + enaconn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &SharpenMicro::enabled_toggled) ); + matrixconn = matrix->signal_toggled().connect( sigc::mem_fun(*this, &SharpenMicro::matrix_toggled) ); +} + +void SharpenMicro::read(const ProcParams* pp, const ParamsEdited* pedited) { + disableListener (); + + if(pedited ){ + enabled->set_inconsistent (!pedited->sharpenMicro.enabled); + matrix->set_inconsistent (!pedited->sharpenMicro.matrix); + amount->setEditedState (pedited->sharpenMicro.amount ? Edited : UnEdited); + uniformity->setEditedState (pedited->sharpenMicro.uniformity ? Edited : UnEdited); + } + enaconn.block (true); + enabled->set_active (pp->sharpenMicro.enabled); + enaconn.block (false); + lastEnabled = 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 = enabled->get_active (); + pp->sharpenMicro.matrix = matrix->get_active (); + pp->sharpenMicro.amount = amount->getValue (); + pp->sharpenMicro.uniformity = uniformity->getValue (); + + if (pedited) { + pedited->sharpenMicro.enabled = !enabled->get_inconsistent(); + pedited->sharpenMicro.matrix = !matrix->get_inconsistent(); + pedited->sharpenMicro.amount = amount->getEditedState (); + pedited->sharpenMicro.uniformity = uniformity->getEditedState (); + } +} + +void SharpenMicro::enabled_toggled () { + if (batchMode) { + if (enabled->get_inconsistent()) { + enabled->set_inconsistent (false); + enaconn.block (true); + enabled->set_active (false); + enaconn.block (false); + } + else if (lastEnabled) + enabled->set_inconsistent (true); + + lastEnabled = enabled->get_active (); + } + + if (listener) { + if (enabled->get_active ()) + 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 && enabled->get_active ()) { + 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 && enabled->get_active()) { + 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..e0e3a43e0 --- /dev/null +++ b/rtgui/sharpenmicro.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 . + * + * + * Manuel Llorens' algorithm of micro-contrast sharpening + * + * + */ +#ifndef _SHARPENMICRO_H_ +#define _SHARPENMICRO_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" + +class SharpenMicro : public Gtk::VBox, public AdjusterListener, public FoldableToolPanel { + +protected: + + Gtk::CheckButton* enabled; + Gtk::CheckButton* matrix; + Adjuster* amount; + Adjuster* uniformity; + + bool lastEnabled; + sigc::connection enaconn; + 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 enabled_toggled (); + void matrix_toggled (); + + +}; + +#endif diff --git a/rtgui/shcselector.cc b/rtgui/shcselector.cc new file mode 100644 index 000000000..891c14a44 --- /dev/null +++ b/rtgui/shcselector.cc @@ -0,0 +1,246 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 +#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); + 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); + 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); + 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; + else 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; + else if (movingPosition <3 && 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..c0f69455d --- /dev/null +++ b/rtgui/splash.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 "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; + +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; + version = create_pango_layout (versionString); + version->get_pixel_size (w, h); + window->draw_layout(gc_, pixbuf->get_width() - w - 4, pixbuf->get_height() - h - 4, 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..087354671 --- /dev/null +++ b/rtgui/thresholdadjuster.cc @@ -0,0 +1,331 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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_border_width (2); + + 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; +} + +inline void ThresholdAdjuster::getValue (Glib::ustring& bottom, Glib::ustring& top) { + tSelector.getPositions (bottom, top); +} + +inline 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; +} + +inline 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]); + 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]); + 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..8b8c965ae --- /dev/null +++ b/rtgui/thresholdadjuster.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 _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) {} +}; + + +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 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..9969cb015 --- /dev/null +++ b/rtgui/thresholdselector.cc @@ -0,0 +1,670 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 () { + + 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); + 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); +} + +/* + * 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) { + 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); + 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 { + 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.7, c.get_green_p()*0.7, c.get_blue_p()*0.7); + } + 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); + 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); + 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; + + // 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]; + updateTooltip(); + queue_draw (); +} + +inline 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; +} + +inline void ThresholdSelector::setBgCurveProvider (ThresholdCurveProvider* provider) { + bgCurveProvider = provider; +} + +inline void ThresholdSelector::setSeparatedSliders(bool separated) { + separatedSliders = separated; +} + +inline 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..e17aca595 --- /dev/null +++ b/rtgui/thresholdselector.h @@ -0,0 +1,218 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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; + + 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 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..ab0fe0615 --- /dev/null +++ b/rtgui/thumbbrowserbase.cc @@ -0,0 +1,1018 @@ +/* + * 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) { + inTabMode=false; // corresponding to take thumbSize + 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) ); + signal_style_changed().connect( sigc::mem_fun(*this, &ThumbBrowserBase::styleChanged) ); +} + +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::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::styleChanged (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) { + inTabMode = enable; + arrangement = inTabMode ? ThumbBrowserBase::TB_Horizontal : ThumbBrowserBase::TB_Vertical; + + if (!options.sameThumbSize && (options.thumbSizeTab!=options.thumbSize)) { + #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 (inTabMode) { + 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..1892b49b1 --- /dev/null +++ b/rtgui/thumbbrowserbase.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 _THUMBNAILBROWSERBASE_ +#define _THUMBNAILBROWSERBASE_ + +#include +#include "thumbbrowserentrybase.h" +#include +#include "options.h" +#include "guiutils.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; } + }; + + 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; + + bool inTabMode; // Tab mode has e.g. different preview heights + + 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: + + 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); + + 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 styleChanged (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..865291228 --- /dev/null +++ b/rtgui/thumbbrowserentrybase.cc @@ -0,0 +1,449 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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) {} + +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 (options.showFileNames && options.overlayedFileNames) { + 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 = igap; + int iheight = 0; + for (size_t i=0; iget_width() + igap; + if (bbIcons[i]->get_height() > iheight) + iheight = bbIcons[i]->get_height(); + } + iheight += 2*igap; + if (!options.overlayedFileNames) { + cr->begin_new_path (); + cr->rectangle (istartx-igap, istarty-igap, iwidth, iheight); + cr->set_source_rgba (0, 0, 0, 0.75); + 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( options.showFileNames ){ + int textposx_fn, textposx_ex, textposx_dt, textposy, textw; + if (!options.overlayedFileNames) { + 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); + + // 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); + + // 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); + + // calculate cummulated height of all info fields + infoh = fnlabh; + infow = 0; + // add date/tile size: + if (options.fbShowDateTime) { + infoh += dtlabh; + if (dtlabw + 2*sideMargin > infow) + infow = dtlabw + 2*sideMargin; + } + if (options.fbShowBasicExif) { + infoh += exlabh; + if (exlabw + 2*sideMargin > infow) + infow = exlabw + 2*sideMargin; + } +} + +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); + + // calculate the height remaining for the thumbnail image + preh = height - upperMargin - 2*borderWidth - lowerMargin - bsh; + int infow=0; + int infoh=0; + if (options.showFileNames && !options.overlayedFileNames) { + // dimensions of the info text + getTextSizes (infow, infoh); + infoh += textGap; + preh -= 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 (options.showFileNames && !options.overlayedFileNames) { + 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 && yx+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 (!options.showFileNames && inside(x,y) && tooltip.empty()) { + tooltip = dispname; + if (options.fbShowDateTime && datetimeline!="") tooltip += Glib::ustring("\n") + datetimeline; + if (options.fbShowBasicExif && exifline!="") tooltip += Glib::ustring("\n") + exifline; + } + + return tooltip; +} + + diff --git a/rtgui/thumbbrowserentrybase.h b/rtgui/thumbbrowserentrybase.h new file mode 100644 index 000000000..7e1baac07 --- /dev/null +++ b/rtgui/thumbbrowserentrybase.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 _THUMBNAILBROWSERENTRYBASE_ +#define _THUMBNAILBROWSERENTRYBASE_ + +#include +#include "lwbuttonset.h" +#include "thumbnail.h" +#include "threadutils.h" + +class ThumbBrowserBase; +class ThumbBrowserEntryBase { + +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; + + 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); + 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..380f204a8 --- /dev/null +++ b/rtgui/thumbimageupdater.cc @@ -0,0 +1,320 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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; + #ifdef _OPENMP + threadCount=omp_get_num_procs(); + #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..f1e4f554a --- /dev/null +++ b/rtgui/thumbnail.cc @@ -0,0 +1,910 @@ +/* + * 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_); + } + + } // 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"); + 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("File not found\n"); + 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..7a15af731 --- /dev/null +++ b/rtgui/tonecurve.cc @@ -0,0 +1,716 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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" + +using namespace rtengine; +using namespace rtengine::procparams; + +ToneCurve::ToneCurve () : Gtk::VBox(), FoldableToolPanel(this) { + + set_border_width(4); + set_spacing(4); + + 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); + + 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) ); + + sclip = Gtk::manage (new MySpinButton ()); + sclip->set_range (0.0, 0.99); + sclip->set_increments (0.01, 0.01); + sclip->set_value (0.02); + sclip->set_digits (2); + sclip->set_tooltip_text (M("TP_EXPOSURE_CLIP_TIP")); + 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); + // pack_end is used for these controls as autolevels is replaceable using pack_start in batchmode + abox->pack_end (*neutral); + abox->pack_end (*Gtk::manage (new Gtk::Label (" "))); //spacer + abox->pack_end (*sclip); + abox->pack_end (*Gtk::manage (new Gtk::Label (M("TP_EXPOSURE_CLIP")))); + 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->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->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->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->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(4); + } + if (!pedited->toneCurve.curveMode2) { + toneCurveMode2->set_active(4); + } + } + 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::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; + + 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; + + 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() != 4; + pedited->toneCurve.curveMode2 = toneCurveMode2->get_active_row_number() != 4; + } + 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; +} + +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); + 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); + 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")); + + curveEditorG->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..b5fc5c9d0 --- /dev/null +++ b/rtgui/tonecurve.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 _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 Gtk::VBox, 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; + 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 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..c90677dcd --- /dev/null +++ b/rtgui/toolbar.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 "toolbar.h" +#include "multilangmgr.h" +#include "rtimage.h" +#include "guiutils.h" + +ToolBar::ToolBar () : listener (NULL) { + + handTool = Gtk::manage (new Gtk::ToggleButton ()); + Gtk::Image* handimg = Gtk::manage (new RTImage ("openhand.png")); + 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")); +} + +// +// 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); + + 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); +} + +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; + } + 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: + wb_pressed (); + return true; + 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..3217f33a0 --- /dev/null +++ b/rtgui/toolbar.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 __TOOLBAR_H__ +#define __TOOLBAR_H__ + +#include +#include "toolenum.h" + +class ToolBarListener { + + public: + virtual void toolSelected (ToolMode tool) {} + +}; + +class ToolBar : public Gtk::HBox { + + protected: + Gtk::ToggleButton* handTool; + Gtk::ToggleButton* wbTool; + Gtk::ToggleButton* cropTool; + Gtk::ToggleButton* straTool; + ToolBarListener* listener; + ToolMode current; + sigc::connection handConn; + sigc::connection wbConn; + sigc::connection cropConn; + sigc::connection straConn; + + public: + ToolBar (); + + void setTool (ToolMode tool); + ToolMode getTool () { return current; } + + void setToolBarListener (ToolBarListener* tpl) { listener = tpl; } + + 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..6d8a7935b --- /dev/null +++ b/rtgui/toolpanel.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 "toolpanel.h" +#include "toolpanelcoord.h" + +using namespace rtengine::procparams; + + +class Frame2: public Gtk::Frame +{ + Gtk::Container *pC; +public: + Frame2( Gtk::Container *p):pC(p){} + ~Frame2( ){ delete pC;} +}; + +FoldableToolPanel::FoldableToolPanel(Gtk::Box* content) : ToolPanel(), parentContainer(NULL), exp(NULL) { + + exp = Gtk::manage (new Gtk::Expander ()); + exp->set_border_width (4); + exp->set_use_markup (true); + exp->signal_button_release_event().connect_notify( sigc::mem_fun(this, &FoldableToolPanel::foldThemAll) ); + + Frame2* pframe = Gtk::manage (new Frame2 (content)); + + pframe->set_name ("ToolPanel"); + + pframe->add (*content); + + exp->add (*pframe); + pframe->set_shadow_type (Gtk::SHADOW_ETCHED_IN); + pframe->show (); + 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::setLabel (Glib::ustring label, bool need100Percent) { + if (!need100Percent) + exp->set_label(Glib::ustring("") + label + Glib::ustring("")); + else { + Gtk::Label *labelWidget = Gtk::manage (new Gtk::Label(Glib::ustring("") + label + Glib::ustring(""))); + labelWidget->set_use_markup(); + RTImage *image = Gtk::manage (new RTImage("zoom-100-identifier.png")); + image->set_tooltip_text(M("TP_GENERAL_11SCALE_TOOLTIP")); + Gtk::HBox *hbox = Gtk::manage (new Gtk::HBox()); + + hbox->set_spacing(4); + hbox->pack_start(*labelWidget, false, false, 0); + hbox->pack_end(*image, false, false, 0); + exp->set_label_widget(*hbox); + exp->set_label_fill(); + } +} diff --git a/rtgui/toolpanel.h b/rtgui/toolpanel.h new file mode 100644 index 000000000..cae6cd949 --- /dev/null +++ b/rtgui/toolpanel.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 __TOOLPANEL__ +#define __TOOLPANEL__ + +#include +#include +#include "../rtengine/rtengine.h" +#include "../rtengine/procparams.h" +#include "multilangmgr.h" +#include "paramsedited.h" + +class ToolPanel; +class FoldableToolPanel; + +class ToolPanelListener { + + public: + + virtual ~ToolPanelListener() {} + virtual void panelChanged (rtengine::ProcEvent event, const Glib::ustring& descr) {} +}; + +class ToolPanel { + + protected: + 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 + + public: + + ToolPanel () : listener(NULL), tmp(NULL), batchMode(false), multiImage(false) {} + virtual ~ToolPanel() {} + + void setParent (Gtk::Box* parent) {} + Gtk::Box* getParent () { return NULL; } + void setMultiImage (bool m) { multiImage = m; } + void setListener (ToolPanelListener* tpl) { listener = tpl; } + 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; + void foldThemAll (GdkEventButton* event); + + public: + Gtk::Expander* exp; + + FoldableToolPanel(Gtk::Box* content); + + void setParent (Gtk::Box* parent) { parentContainer = parent; } + Gtk::Box* getParent () { return parentContainer; } + void setLabel (Glib::ustring label, bool need100Percent=false); +}; + +#endif diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc new file mode 100644 index 000000000..729043ae0 --- /dev/null +++ b/rtgui/toolpanelcoord.cc @@ -0,0 +1,650 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 "ilabel.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" +#include "guiutils.h" +#include "rtimage.h" + +using namespace rtengine::procparams; + +ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL) { + + exposurePanel = Gtk::manage (new Gtk::VBox ()); + detailsPanel = Gtk::manage (new Gtk::VBox ()); + colorPanel = Gtk::manage (new Gtk::VBox ()); + transformPanel = Gtk::manage (new Gtk::VBox ()); + rawPanel = Gtk::manage (new Gtk::VBox ()); + + 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 ()); + edgePreservingDecompositionUI = 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 ()); + 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 ()); + crop = Gtk::manage (new Crop ()); + icm = Gtk::manage (new ICMPanel ()); + exifpanel = Gtk::manage (new ExifPanel ()); + iptcpanel = Gtk::manage (new IPTCPanel ()); + dirpyrequalizer = Gtk::manage (new DirPyrEqualizer ()); + hsvequalizer = Gtk::manage (new HSVEqualizer ()); + rawprocess = Gtk::manage (new RawProcess ()); + 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 ()); + + addPanel (colorPanel, whitebalance, M("TP_WBALANCE_LABEL")); toolPanels.push_back (whitebalance); + addPanel (exposurePanel, toneCurve, M("TP_EXPOSURE_LABEL")); toolPanels.push_back (toneCurve); + addPanel (colorPanel, vibrance, M("TP_VIBRANCE_LABEL")); toolPanels.push_back (vibrance); + addPanel (colorPanel, chmixer, M("TP_CHMIXER_LABEL")); toolPanels.push_back (chmixer); + addPanel (colorPanel, blackwhite, M("TP_BWMIX_LABEL")); toolPanels.push_back (blackwhite); + addPanel (exposurePanel, shadowshighlights, M("TP_SHADOWSHLIGHTS_LABEL")); toolPanels.push_back (shadowshighlights); + addPanel (detailsPanel, sharpening, M("TP_SHARPENING_LABEL"), true); toolPanels.push_back (sharpening); + addPanel (detailsPanel, sharpenEdge, M("TP_SHARPENEDGE_LABEL"), true); toolPanels.push_back (sharpenEdge); + addPanel (detailsPanel, sharpenMicro, M("TP_SHARPENMICRO_LABEL"), true); toolPanels.push_back (sharpenMicro); + addPanel (colorPanel, hsvequalizer, M("TP_HSVEQUALIZER_LABEL")); toolPanels.push_back (hsvequalizer); + addPanel (colorPanel, rgbcurves, M("TP_RGBCURVES_LABEL")); toolPanels.push_back (rgbcurves); + addPanel (exposurePanel, edgePreservingDecompositionUI, M("TP_EPD_LABEL")); toolPanels.push_back (edgePreservingDecompositionUI); + addPanel (exposurePanel, pcvignette, M("TP_PCVIGNETTE_LABEL")); toolPanels.push_back (pcvignette); + addPanel (exposurePanel, gradient, M("TP_GRADIENT_LABEL")); toolPanels.push_back (gradient); + addPanel (exposurePanel, lcurve, M("TP_LABCURVE_LABEL")); toolPanels.push_back (lcurve); +// addPanel (exposurePanel, edgePreservingDecompositionUI, M("TP_EPD_LABEL")); toolPanels.push_back (edgePreservingDecompositionUI); + addPanel (exposurePanel, colorappearance, M("TP_COLORAPP_LABEL")); toolPanels.push_back (colorappearance); + addPanel (detailsPanel, impulsedenoise, M("TP_IMPULSEDENOISE_LABEL"), true); toolPanels.push_back (impulsedenoise); + addPanel (detailsPanel, dirpyrdenoise, M("TP_DIRPYRDENOISE_LABEL"), true); toolPanels.push_back (dirpyrdenoise); + addPanel (detailsPanel, defringe, M("TP_DEFRINGE_LABEL"), true); toolPanels.push_back (defringe); + addPanel (detailsPanel, dirpyrequalizer, M("TP_DIRPYREQUALIZER_LABEL"), true); toolPanels.push_back (dirpyrequalizer); + addPanel (transformPanel, crop, M("TP_CROP_LABEL")); toolPanels.push_back (crop); + addPanel (transformPanel, resize, M("TP_RESIZE_LABEL")); toolPanels.push_back (resize); + addPanel (transformPanel, lensgeom, M("TP_LENSGEOM_LABEL")); toolPanels.push_back (lensgeom); + addPanel (lensgeom->getPackBox(), rotate, M("TP_ROTATE_LABEL")); toolPanels.push_back (rotate); + addPanel (lensgeom->getPackBox(), perspective, M("TP_PERSPECTIVE_LABEL")); toolPanels.push_back (perspective); + addPanel (lensgeom->getPackBox(), lensProf, M("TP_LENSPROFILE_LABEL")); toolPanels.push_back (lensProf); + addPanel (lensgeom->getPackBox(), distortion, M("TP_DISTORTION_LABEL")); toolPanels.push_back (distortion); + addPanel (lensgeom->getPackBox(), cacorrection, M("TP_CACORRECTION_LABEL")); toolPanels.push_back (cacorrection); + addPanel (lensgeom->getPackBox(), vignetting, M("TP_VIGNETTING_LABEL")); toolPanels.push_back (vignetting); + addPanel (colorPanel, icm, M("TP_ICM_LABEL")); toolPanels.push_back (icm); + addPanel (rawPanel, rawprocess, M("TP_RAW_LABEL"), true); toolPanels.push_back (rawprocess); + addPanel (rawPanel, preprocess, M("TP_PREPROCESS_LABEL"), true); toolPanels.push_back (preprocess); + addPanel (rawPanel, rawexposure, M("TP_EXPOSCORR_LABEL")); toolPanels.push_back (rawexposure); + addPanel (rawPanel, darkframe, M("TP_DARKFRAME_LABEL")); toolPanels.push_back (darkframe); + addPanel (rawPanel, flatfield, M("TP_FLATFIELD_LABEL")); toolPanels.push_back (flatfield); + addPanel (rawPanel, rawcacorrection, M("TP_CHROMATABERR_LABEL")); toolPanels.push_back (rawcacorrection); + + 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 ()); + + updateVScrollbars (options.hideTPVScrollbar); + + // load panel endings + for (int i=0; i<5; 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,4); + exposurePanel->pack_start (*vbPanelEnd[0],Gtk::PACK_SHRINK,4); + + detailsPanelSW->add (*detailsPanel); + detailsPanel->pack_start (*Gtk::manage(new Gtk::HSeparator), Gtk::PACK_SHRINK,4); + detailsPanel->pack_start (*vbPanelEnd[1],Gtk::PACK_SHRINK,4); + + colorPanelSW->add (*colorPanel); + colorPanel->pack_start (*Gtk::manage(new Gtk::HSeparator), Gtk::PACK_SHRINK,4); + colorPanel->pack_start (*vbPanelEnd[2],Gtk::PACK_SHRINK,4); + + transformPanelSW->add (*transformPanel); + transformPanel->pack_start (*Gtk::manage(new Gtk::HSeparator), Gtk::PACK_SHRINK,4); + transformPanel->pack_start (*vbPanelEnd[3],Gtk::PACK_SHRINK,4); + + rawPanelSW->add (*rawPanel); + rawPanel->pack_start (*Gtk::manage(new Gtk::HSeparator), Gtk::PACK_SHRINK,4); + rawPanel->pack_start (*vbPanelEnd[4],Gtk::PACK_SHRINK,4); + + 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)); + 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 (*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, Glib::ustring label, bool need100Percent) { + + 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); + panel->setLabel(escapeHtmlChars(label), need100Percent); + + expList.push_back (panel->exp); + where->pack_start(*panel->exp, 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); + 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; + std::vector lParams(2); + lParams[0]=*params; lParams[1]=*mergedParams; + pe.set(true); + 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->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::readOptions () { + + crop->readOptions (); + for (size_t i=0; iset_expanded (options.tpOpen.at(i)); +} + +void ToolPanelCoordinator::writeOptions () { + + crop->writeOptions (); + options.tpOpen.clear (); + for (size_t i=0; iget_expanded ()); +} + + +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; +} +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) { + + if (ipc) + ipc->saveInputICCReference (fname); +} + +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) { + + FoldableToolPanel* currentTP; + + for (size_t i=0; i(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->exp->set_expanded(false); + } + else { + if (!currentTP->exp->get_expanded()) + currentTP->exp->set_expanded(true); + } + } + } +} + +bool ToolPanelCoordinator::handleShortcutKey (GdkEventKey* event) { + + //bool ctrl = event->state & GDK_CONTROL_MASK; temporarilly removed because unused + //bool shift = event->state & GDK_SHIFT_MASK; temporarilly 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_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); +} + +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->exp->set_expanded(true); + toolPanelNotebook->set_current_page(toolPanelNotebook->page_num(*transformPanelSW)); + break; + case TMSpotWB: + whitebalance->exp->set_expanded(true); + toolPanelNotebook->set_current_page(toolPanelNotebook->page_num(*colorPanelSW)); + break; + case TMStraighten: + lensgeom->exp->set_expanded(true); + rotate->exp->set_expanded(true); + toolPanelNotebook->set_current_page(toolPanelNotebook->page_num(*transformPanelSW)); + break; + default: + break; + } +} + +void ToolPanelCoordinator::dirSelected (const Glib::ustring& dirname, const Glib::ustring& openfile) { + + flatfield->setShortcutPath(dirname); +} diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h new file mode 100644 index 000000000..47415a33a --- /dev/null +++ b/rtgui/toolpanelcoord.h @@ -0,0 +1,258 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 "dirpyrequalizer.h" +#include "hsvequalizer.h" +#include "rawprocess.h" +#include "preprocess.h" +#include "darkframe.h" +#include "flatfield.h" +#include "rawcacorrection.h" +#include "rawexposure.h" +#include "sharpenmicro.h" +#include "sharpenedge.h" +#include "rgbcurves.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; + ICMPanel* icm; + Crop* crop; + ToneCurve* toneCurve; + ShadowsHighlights* shadowshighlights; + Defringe* defringe; + ImpulseDenoise* impulsedenoise; + DirPyrDenoise* dirpyrdenoise; + EdgePreservingDecompositionUI *edgePreservingDecompositionUI; + Sharpening* sharpening; + SharpenEdge* sharpenEdge; + SharpenMicro* sharpenMicro; + LCurve* lcurve; + RGBCurves* rgbcurves; + DirPyrEqualizer * dirpyrequalizer; + HSVEqualizer * hsvequalizer; + RawProcess* rawprocess; + PreProcess* preprocess; + DarkFrame* darkframe; + FlatField* flatfield; + RAWCACorr* rawcacorrection; + RAWExposure* rawexposure; + + std::vector paramcListeners; + + rtengine::StagedImageProcessor* ipc; + + std::vector toolPanels; + Gtk::VBox* exposurePanel; + Gtk::VBox* detailsPanel; + Gtk::VBox* colorPanel; + Gtk::VBox* transformPanel; + Gtk::VBox* rawPanel; + Gtk::Notebook* metadataPanel; + ExifPanel* exifpanel; + IPTCPanel* iptcpanel; + ToolBar* toolBar; + + TextOrIcon* toiE; + TextOrIcon* toiD; + TextOrIcon* toiC; + TextOrIcon* toiT; + TextOrIcon* toiR; + TextOrIcon* toiM; + + 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[5]; + Gtk::VBox* vbPanelEnd[5]; + + Gtk::ScrolledWindow* exposurePanelSW; + Gtk::ScrolledWindow* detailsPanelSW; + Gtk::ScrolledWindow* colorPanelSW; + Gtk::ScrolledWindow* transformPanelSW; + Gtk::ScrolledWindow* rawPanelSW; + + std::vector expList; + + bool hasChanged; + + void addPanel (Gtk::Box* where, FoldableToolPanel* panel, Glib::ustring label, bool need100Percent=false); + void foldThemAll (GdkEventButton* event); + void updateVScrollbars (bool hide); + void updateTabsHeader (bool useIcons); + + 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 (); + + // 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(); + + // 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); + + // 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); + + void toolSelected (ToolMode tool); +}; + +#endif diff --git a/rtgui/version.h.in b/rtgui/version.h.in new file mode 100644 index 000000000..335e2840d --- /dev/null +++ b/rtgui/version.h.in @@ -0,0 +1,12 @@ +// 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 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..0eab03a0b --- /dev/null +++ b/rtgui/vibrance.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 "vibrance.h" +#include "../rtengine/color.h" +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +Vibrance::Vibrance () : Gtk::VBox(), FoldableToolPanel(this) { + + set_border_width(4); + + 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)) ); + + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); + enabled->set_active (false); + pack_start(*enabled, Gtk::PACK_SHRINK, 0); + + pack_start (*Gtk::manage (new Gtk::HSeparator())); + + 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 (); + + enaconn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &Vibrance::enabled_toggled) ); + 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 ){ + enabled->set_inconsistent (!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); + } + + enaconn.block (true); + enabled->set_active (pp->vibrance.enabled); + enaconn.block (false); + lastEnabled = 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 = enabled->get_active (); + 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 = !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 && enabled->get_active()) listener->panelChanged (EvVibranceSkinTonesCurve, M("HISTORY_CUSTOMCURVE")); +} + +void Vibrance::enabled_toggled () { + if (batchMode) { + if (enabled->get_inconsistent()) { + enabled->set_inconsistent (false); + enaconn.block (true); + enabled->set_active (false); + enaconn.block (false); + } + else if (lastEnabled) + enabled->set_inconsistent (true); + + lastEnabled = enabled->get_active (); + } + + if (listener) { + if (enabled->get_active ()) + 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 && enabled->get_active()) { + 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 && enabled->get_active()) { + 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 && enabled->get_active()) { + 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 && enabled->get_active()) { + 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 && enabled->get_active()) { + 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..440afa0bb --- /dev/null +++ b/rtgui/vibrance.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 _VIBRANCE_ +#define _VIBRANCE_ + +#include +#include "adjuster.h" +#include "thresholdadjuster.h" +#include "curveeditor.h" +#include "curveeditorgroup.h" +#include "toolpanel.h" + +class Vibrance : public Gtk::VBox, public AdjusterListener, public ThresholdCurveProvider, public ThresholdAdjusterListener, + public FoldableToolPanel, public CurveListener +{ + +protected: + CurveEditorGroup* curveEditorGG; + + Gtk::CheckButton* enabled; + Adjuster* pastels; + Adjuster* saturated; + ThresholdAdjuster* psThreshold; + Gtk::CheckButton* protectSkins; + Gtk::CheckButton* avoidColorShift; + Gtk::CheckButton* pastSatTog; + DiagonalCurveEditor* skinTonesCurve; + + bool lastEnabled; + bool lastProtectSkins; + bool lastAvoidColorShift; + bool lastPastSatTog; + + sigc::connection enaconn; + 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 enabled_toggled (); + 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..b968c82be --- /dev/null +++ b/rtgui/vignetting.cc @@ -0,0 +1,155 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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" +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +Vignetting::Vignetting () : Gtk::VBox(), FoldableToolPanel(this) { + + set_border_width(4); + + 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..45d8b603a --- /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 Gtk::VBox, 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/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..029b0da0a --- /dev/null +++ b/rtgui/whitebalance.cc @@ -0,0 +1,728 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 () : Gtk::VBox(), FoldableToolPanel(this), wbp(NULL), wblistener(NULL) { + + set_border_width(4); + + 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..5e932fe25 --- /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 Gtk::VBox, 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/zoompanel.cc b/rtgui/zoompanel.cc new file mode 100644 index 000000000..e869e9729 --- /dev/null +++ b/rtgui/zoompanel.cc @@ -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 . + */ +#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); + + 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); + 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 (*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) ); + 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")); + 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::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..27bc0fa9e --- /dev/null +++ b/rtgui/zoompanel.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. + *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* zoom11; + Gtk::Button* newCrop; + Gtk::Label* zoomLabel; + ImageArea* iarea; + + public: + + ZoomPanel (ImageArea* iarea); + + void zoomInClicked (); + void zoomOutClicked (); + void zoomFitClicked (); + void zoom11Clicked (); + void newCropClicked (); + void refreshZoomLabel (); +}; + +#endif + diff --git a/tools/RTProfileBuilderSample.cs b/tools/RTProfileBuilderSample.cs new file mode 100644 index 000000000..20a3b8e1c --- /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..5cf73802c --- /dev/null +++ b/tools/buildRT @@ -0,0 +1,382 @@ +#!/usr/bin/env bash +# Written by DrSlony +# buildRT version 3.7, 2013-12-30 +# 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 +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="3.7" +movetoPatched="" +repo="${HOME}/rawtherapee" +procTarget=2 + +while getopts "bc:np: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" + #sanitize + dCacheNameSuffix=${dCacheNameSuffix//[^\.\-_a-zA-Z0-9]/}; + printf "%s\n" "Cache and config name suffix: $dCacheNameSuffix" ;; + n) noomp="-DOPTION_OMP=OFF" + 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 + fi ;; + 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 ] [-n] [-p <1-9>] [-v]" "" \ + " -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." "" \ + " -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" "" \ + " -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 'RawTherapee-{latesttag}.{latesttagdistance}, Latest tag: {latesttag}, Latest tag distance: {latesttagdistance}, Changeset: {rev}:{node|short}\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 + 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 + hg parents --template 'Repository head:\n RawTherapee-{latesttag}.{latesttagdistance}\n Latest tag: {latesttag}\n Latest tag distance: {latesttagdistance}\n Changeset: {rev}:{node|short}\n\n' +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" + movetoPatched="_patched" ;; + *) printf "%s\n" "User aborted" "" + exit 0 ;; + esac +else + printf "%s\n" "Retaining edited source code and compiling RT as-is." "" + movetoPatched="_patched" +fi + +#--- Print the menu +branches=() +if [[ -z $patched ]]; then + while read -r branch; do + branches+=("$branch") + done < <(hg branches -q) +else + branches="$(hg branch)" +fi +num="1" +# Can't print the list[0] "clone repository" text nicely when using "column -t", +# so fill list[0] with junk to start counting from 1 and printf the 0 option manually later on +list[0]="# - Branch - Buildtype" +buildTypes=("Release" "Debug") +for branch in "${branches[@]}"; do + for buildType in "${buildTypes[@]}"; do + list+=("$num - ${branch} - ${buildType}") + ((num++)) + done +done +((num--)) +# ^ Because of num++ in the for loop increasing a number after the last list item +printf "%s\n" "------------------------------------------" +printf "%s\n" "${list[0]}" +printf "%s\n" "------------------------------------------" +printf "%s\n" "0 - abort - exit" "${list[@]:1}" | column -t +printf "%s\n" "------------------------------------------" "" "Enter your choices, each number separated by a single space, e.g. 1 2" "If you don't know which option to choose, then choose the \"default\" branch, \"Release\" build type." "" | fold -s +while [[ -z $choiceNumbers ]]; do + read -r -p "Your choices: " -a choiceNumbers +done +printf "%s\n" "" "------------------------------------------" +#sanitize +choiceNumbers="${choiceNumbers//[^0-9 ]/}" + +#--- Compile the chosen builds +for choiceNumber in ${choiceNumbers[*]}; do + if [[ $choiceNumber = 0 ]]; then + printf "%s\n" "User exited." + exit 0; + fi + read -r _ _ branch _ buildType < <(printf "%s\n" "${list[$choiceNumber]}") + # 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" "Starting to compile:" "" "\tChoice number:" "$choiceNumber" "\tBranch:" "$branch" "\tBuild type:" "$buildType" "\tTarget:" "$procTarget" "" "" + rev="$(hg parents --template {rev})" + + # 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"; } + [[ -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}${movetoPatched}X\" where \"X\" will be replaced with whatever suffix you choose next. Only alphanumerics, dashes and underscores 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\"" + esac + } + + # Clean up old CMake junk + cd "${repo}" || exit 1 + 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; } + echo + + # print current line in script: + # printf "%s\n" "LINENO is \"$LINENO\", BASH_LINENO[i] is \"${BASH_LINENO[$i]}\". Patched is $patched" + + printf "%s\n" "" "Starting compilation:" + verLatesttag="$(hg parents --template '{latesttag}')" + verLatesttagdistance="$(hg parents --template '{latesttagdistance}')" + [[ -z $dCacheNameSuffix ]] && dCacheNameSuffix="${verLatesttag%%.*}" + + 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" ../ \ + || { echo "Error during cmake, exiting."; exit 1; } + fi + + 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 "%s\n" "" "To run RawTherapee, 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/generateReleaseInfo b/tools/generateReleaseInfo new file mode 100755 index 000000000..c53ac1fb4 --- /dev/null +++ b/tools/generateReleaseInfo @@ -0,0 +1,14 @@ +#!/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) +if (CACHE_NAME_SUFFIX STREQUAL \"\") + set(CACHE_NAME_SUFFIX $hgLatesttag) +endif()" > ReleaseInfo.cmake + diff --git a/tools/generateReleaseInfo.bat b/tools/generateReleaseInfo.bat new file mode 100644 index 000000000..1f0e21d70 --- /dev/null +++ b/tools/generateReleaseInfo.bat @@ -0,0 +1,14 @@ +@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 +echo if (CACHE_NAME_SUFFIX STREQUAL "") >> ReleaseInfo.cmake +echo set(CACHE_NAME_SUFFIX %hgLatesttag%) >> ReleaseInfo.cmake +echo endif() >> 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..3044b57cf --- /dev/null +++ b/tools/generateUnusedKeys @@ -0,0 +1,99 @@ +#!/usr/bin/env bash + +# This Bash4 script checks whether each key in "default" appears in +# a .cc or .h file. Those that do 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 not skipped, so they will remain +# in the language files. +# It does not handle dynamically built keys: +# HISTORY_MSG_ +# EXTPROGTARGET_ +# FILEBROWSER_POPUPRANK +# FILEBROWSER_POPUPCOLORLABEL +# +# Run the script from the project root: +# ./tools/generateUnusedKeys +# +# Doublecheck the deletion before committing. +# Run ./tools/generateTranslationDiffs after running this script. + +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 -Irl -m1 --include=\*.{cc,h} --exclude-dir="klt" "${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. +# 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. + +t2="$(date +%s)" +tt=$((t2-t1)) +printf "%s\n" "" "Scan took $tt seconds" "" + +read -r -p 'Write results to "unmatched"? [y/n] ' +if [[ $REPLY = y || $REPLY = Y ]]; then + printf "%s\n" "${delLines[@]}" > unmatched + printf "%s\n" "" +fi + +read -r -p "Delete 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 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/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.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-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.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.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/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-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-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/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..6ee85db38 --- /dev/null +++ b/tools/source_icons/script/svg2png.bash @@ -0,0 +1,60 @@ +#! /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 + 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 + + 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..2259c144f --- /dev/null +++ b/win.cmake @@ -0,0 +1,50 @@ +# 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") + +# 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")