commit a82fb5aea99b4440b1b9f8cbe3b72569bfd20e6a Author: michael Date: Tue Oct 16 21:49:34 2012 -0400 Enhancement to Find by Filename filter - support for comma-separated values (issue 1594) diff --git a/.hgignore b/.hgignore new file mode 100644 index 000000000..e93bfaffa --- /dev/null +++ b/.hgignore @@ -0,0 +1,24 @@ +syntax: glob + +*~ +*.orig + +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 diff --git a/AUTHORS.txt b/AUTHORS.txt new file mode 100644 index 000000000..5162073cf --- /dev/null +++ b/AUTHORS.txt @@ -0,0 +1,37 @@ + +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 + +Other contributors (profiles, ideas, mockups, testing, forum activity, translations, etc.), in last name alphabetical order: + + Thorsten Bartolomäus + Patrik Brunner + Fernando Carello + M. Dávid Gyurkó + Arturs Jekabsons + 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..976130136 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,319 @@ +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) +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 +# It were moved away from rtengine/CMakefiles.txt, because some users may want to remove -ffast_math : +# this flag speeds up the floating-point operations, but with a little bite less precisions. This default value +# gives the same result/behaviour as before. +set (RTENGINE_CXX_FLAGS "-ffast-math -funroll-loops" 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) +# SET (CMAKE_OSX_ARCHITECTURES "i386;x86_64;" ) +# SET (CMAKE_TRY_COMPILE_OSX_ARCHITECTURES "i386;x86_64;" ) + SET (CMAKE_OSX_SYSROOT "/Developer/SDKs/MacOSX10.5.sdk") + SET (CMAKE_OSX_DEPLOYMENT_TARGET "10.5") +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 (BUILD_BUNDLE "Self-contained build" 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 () + +# 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) + + set (EXTRA_LIB "-lws2_32") +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) + +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. Please refer e.g. to http://www.cmake.org/Wiki/CMake_FAQ#What_is_an_.22out-of-source.22_build.3F for advantages of o ut of source builds.") +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 +set(CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${UPPER_CMAKE_BUILD_TYPE}}") +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..d011bd781 --- /dev/null +++ b/COMPILE.txt @@ -0,0 +1,508 @@ +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.0.10" as an example: + 1. Check out the desired hg tag: hg update "4.0.10" + 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/ + 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.22 http://www.gtk.org/ + GTKMM gtkmm-2.4>=2.22 http://www.gtkmm.org + JPEG libjpeg>=6b http://libjpeg-turbo.virtualgl.org/ + http://jpegclub.org/ + http://www.ijg.org/ + LCMS2 lcms>=2.0a http://www.littlecms.com/ + 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 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: + + There are two methods of compiling RawTherapee in Windows, and they each + rely on different and common packages. They will be referred to as METHOD 1 + and METHOD 2. You will have to install the dependencies for the build + methods explained later in this document. + + The rest of this document assumes that you've installed MinGW, MSYS and + gtkmm respectively to "C:\mingw", "C:\msys" and "C:\gtkmm". These packages + must be installed in paths that DO NOT CONTAIN SPACES. + + METHOD 1 + - MinGW64-TDM (Bundle or On-Demand installer from + http://tdm-gcc.tdragon.net/download) Make sure you use the current 4.6.1 + or newer stable version, and install MinGW64 (not MinGW32), as MinGW64 + is more comprehensive plus it runs AND compiles for both 32bit and 64bit + Windows machines. Old Mingw32 versions miss some required header files, + so some Windows functions will be disabled though it will compile. + However MinGW64 does not fully support Windows XP, only Vista and up. + - MSYS - http://downloads.sourceforge.net/mingw/MSYS-1.0.11.exe If you + have some trouble installing MSYS, see here: + http://www.mingw.org/wiki/MSYS + - CMake - http://www.cmake.org/cmake/resources/software.html Version 2.8.8 + or above is required for this platform + - gtkmm-2.22 + - for 32bit: + http://ftp.se.debian.org/pub/gnome/binaries/win32/gtkmm/2.22/ + - for 64bit: + http://ftp.gnome.org/pub/gnome/binaries/win64/gtk+/2.22/ + + METHOD 2 + - MinGW-TDM - Bundle or On-Demand installer + http://tdm-gcc.tdragon.net/download + - CMake - http://www.cmake.org/cmake/resources/software.html + - gtkmm-2.22 + - for 32bit: + http://ftp.se.debian.org/pub/gnome/binaries/win32/gtkmm/2.22/ + - for 64bit: + http://ftp.gnome.org/pub/gnome/binaries/win64/gtk+/2.22/ + + ADDITIONAL STEPS: + When all the packages of your preferred method are installed: + - set the GTKMM_BASEPATH user or system environment variable to the + installation directory of gtkmm (the gtkmm installer can do it for you). + - set the MINGW_BASEPATH user or system environment variable to the + installation directory of MinGW32. + - set the PKG_CONFIG_PATH user or system environment variable to the + location of the pkgconfig directories: + c:\mingw\lib\pkgconfig;c:\gtkmm\lib\pkgconfig You have to restart the + console to take these new variables into effect. + - set the CMake option BUILD_BUNDLE ON + - If you run MinGW64 and want to compile for 32bit, change the following + vars in CMake (use CMAKE-GUI to makes this easier): + CMAKE_CXX_FLAGS,CMAKE_C_FLAGS,CMAKE_SHARED_LINKER_FLAGS: -m32 + CMAKE_EXE_LINKER_FLAGS: -m32 --large-address-aware + CMAKE_RC_FLAGS: -F pe-i386 + + - Copy the "Win32CMakeOptions-sample.txt" file located in the root + directory of RT's source tree, to "cmo.txt" (for example). You can edit + that copy to change the compilation flags to your needs, but the default + values should be fine. However, 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 in cmo.txt to the + desired target number. If you choose the 'native' solution, you have + to set the processor label manually in cmo.txt by uncommenting and + setting the PROC_LABEL parameter. 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 have to set the PROC_LABEL + parameter in cmo.txt (don't forget to uncomment the line). Please + provide a short name, like "core i5" or "athlon64" (without double + quotes). Specifying the processor frequency isof no use. + + + DEPENDENCIES: + + RawTherapee depends on libraries which are not part of the gtkmm or MinGW + packages. There are two ways of installing these libraries: + + THE SIMPLE WAY: + For your convenience, most of the required libraries has been precompiled and are + downloadable at: + http://www.rawtherapee.com/releases_head/windows/dependencies_for_creating_builds/ + Unpack the contents of these archives to the base installation dir of + MinGW. + + NOTE: those archives contain most but not all of the required + libraries. See the dependencies list at the beginning of the document, + find the missing ones (such as LCMS2 and Expat) and see below for + instructions on where to download them from and how to install them. + + THE "DO IT YOURSELF" WAY: + The MSYS package is required to build the libraries. See above for the + download link. 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 for RawTherapee-3.1 and newer (or LCMS1 for RawTherapee-3.0) + http://sourceforge.net/projects/lcms/files/ + - How to build (suitable for both version): + ./configure --prefix=/mingw + make + make install + + Expat: + - Download: http://expat.sourceforge.net/ + - Install + + FFTW: + - Instructions: http://www.fftw.org/install/windows.html + + + 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 the following + lines when running the cmake command (see "Building RT" 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 + + BUILDING RT: + + METHOD 1: + Requirements: + - MinGW + MSYS + - CMake + - GTK and gtkmm development environments + + Compile: + - Start an MSYS command line interface, + - Enter a new empty folder outside RawTherapee's source directory: + cd /C/Absolute/Path/To/RawTherapee_sourceTree + mkdir build + cd build + - Type: + cmake -G "MSYS Makefiles" -DCMAKE_BUILD_TYPE=Release -Ccmo.txt \ + + - Type: + make install + - You'll find the compiled program in the subdirectory named like the + value of CMAKE_BUILD_TYPE ("Release" in this example). + + METHOD 2: + Requirements: + - MinGW-TDM: + https://sourceforge.net/projects/tdm-gcc/files/TDM-GCC%20Installer/ + - CMake: http://www.cmake.org/cmake/resources/software.html + - Mercurial: http://mercurial.selenic.com/wiki/WindowsInstall + - gtkmm: http://ftp.se.debian.org/pub/gnome/binaries/win32/gtkmm/2.22/ + + Compile: + - Start a standard DOS command prompt (WIN+R > cmd), + - Enter a new empty folder outside RawTherapee's source directory: + cd /C/Absolute/Path/To/RawTherapee_sourceTree + mkdir build + cd build + 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: + mingw32-make.exe install + - You'll find the compiled program in the subdirectory named like the + value of CMAKE_BUILD_TYPE ("Release" in this example). + +LINUX +----- + + DEPENDENCIES: + See the list of dependencies at the beginning of this document. + + In Ubuntu/Debian the requirements can be installed by running: + sudo apt-get install build-essential cmake libfftw3-dev libbz2-dev \ + libexiv2-dev libexpat1-dev libglib2.0-dev libglibmm-2.4-dev \ + libgtk2.0-dev libgtkmm-2.4-dev libiptcdata-dev libjpeg8-dev \ + liblcms2-dev libpng-dev libsigc++-2.0-dev libtiff-dev mercurial \ + zlib1g-dev + + In Fedora, run: + sudo yum install gcc-c++ cmake bzip2-devel exiv2-devel expat-devel \ + fftw-devel glib2-devel glibmm24-devel gtk+-devel gtkmm24-devel \ + libjpeg-turbo-devel lcms2-devel libiptcdata-devel libpng-devel \ + libsigc++20-devel libtiff-devel zlib-devel + + In Gentoo, run: + sudo emerge -uva app-arch/bzip2 media-gfx/exiv2 dev-libs/expat \ + dev-libs/glib dev-cpp/glibmm x11-libs/gtk+ dev-cpp/gtkmm \ + media-libs/libjpeg-turbo media-libs/lcms media-libs/libiptcdata \ + media-libs/libpng dev-libs/libsigc++ media-libs/tiff sci-libs/fftw \ + sys-libs/zlib + + In Arch, run: + sudo pacman -S bzip2 exiv2 expat fftw glib2 glibmm gtk gtkmm lcms2 \ + libiptcdata libjpeg-turbo libpng libsigc++ libtiff zlib + + 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 + - Set /opt/local/etc/macports/variants.conf to include "+no_x11 +quartz" + - If you want to build for multiple architectures, add +universal to + variants.conf. Note that this will increase the size of the final + application substantially. + - Set /opt/local/etc/macports/macports.conf key 'universal_archs' to the + architectures you wish to build for. Possible values include "i386 + x86_64 ppc ppc64" + - Edit the beginning of CMakeLists.txt to enable the same architectures + as you added to variants.conf + - To install all the tools and dependencies, run: + sudo port install cairomm cmake fftw-3 glibmm gtk2 gtkmm lcms \ + libiptcdata pango-devel + - If you don't already have Mercurial installed, run: + sudo port install mercurial + - If you want to try OpenMP builds, run: + sudo port install gcc45 + + COMPILE: + - Enter the root directory of the RawTherapee source tree + - To enable OpenMP, assuming you have installed gcc45), type: + cmake -D CMAKE_C_COMPILER=gcc-mp-4.5 -D CMAKE_CXX_COMPILER=g++-mp-4.5 \ + + OR to disable OpenMP and use the default compiler, type: + cmake -D OPTION_OMP=false + + 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: + ./tools/osx/make-app-bundle + - You will find a RawTherapee.dmg file in the release/ folder; this is the + distribution release and can be run on any machine which meets the + architecture requirements you specified in variants.conf earlier. + + Contact: For any bugs or patches to the OS X build, please contact Wyatt + 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..504e5cb66 --- /dev/null +++ b/ProcessorTargets.cmake @@ -0,0 +1,37 @@ +# 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 -mtune=athlon64" CACHE STRING "Processor-8 flags") +set(PROC_TARGET_8_FLAGS "-mfpmath=sse -march=athlon64 -mtune=athlon64 -mmmx -msse -msse2 -mthreads -m64" 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..16b773db5 --- /dev/null +++ b/RELEASE_NOTES.txt @@ -0,0 +1,275 @@ +RAWTHERAPEE 4.0.9 RELEASE NOTES +------------------------------- + +NEW FEATURES +------------ +- Support for Adobe LCP lens correction profiles +- Program plugger for Windows, to automatically find and be able to + open right-clicked photos with popular photography programs. +- Support of Dual illuminant DCP profiles +- Support for new cameras in addition to those already supported by dcraw: + - Nikon D800 + - Canon EOS 5D Mark III +- New camera DCP profiles: + - Nikon D5100 + - Nikon D7000 + +Most commits focused on squashing bugs and speeding up processing. + + +CAVEATS +------- +- Risk of PP3 data loss - beware when running multiple RT versions +RawTherapee cleans up obsolete or invalid tags from active PP3 files. This process is run in three situations: +1- When you affect the PP3 file in any way, e.g. by tagging a photo, +2- When you select another folder in the File Browser tab +3- When you exit RawTherapee (equivalent to leaving the open album) +This means that a more recent version of RawTherapee will delete obsolete tags which may have been used by an older version, and vice versa - if you use an old version of RawTherapee to browse photos edited with a newer version, it will delete the tags introduced in the new version. This issue is being worked on, and future versions of RawTherapee will support XMP sidecar files with concurrent embedded profile versions. +http://code.google.com/p/rawtherapee/issues/detail?id=1335 + +- Memory requirements +Please read http://rawtherapee.com/blog/maximizing-memory-efficiency + +- Differences between the preview and the output image +The color-managed preview in RawTherapee is (and has always been) based on image data in the Working Space profile. Although the actual preview is rendered using a monitor profile (or sRGB profile, if the monitor profile is not specified), it does not reflect the Output Profile & Output Gamma settings. This can lead to a slightly different output rendering when Working Space profile and Output Space profiles are not the same. A workaround is to set them to the same values to ensure the preview accurately reflects the final rendered output. + + +DOCUMENTATION +------------- +http://rawtherapee.com/blog/documentation + + +REPORTING BUGS +-------------- +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 +http://rawtherapee.com/forum/viewtopic.php?f=1&t=945#p4603 + + +REVISION HISTORY +---------------- +The complete change log is available at +http://code.google.com/p/rawtherapee/source/list + + +CHANGELOG for 4.0.9 +------------------- + +  DATE | CHANGESET | COMMITTER +  --------------|---------------|------------------------------------- +> 2012-06-03 | 599d1e925de0 | Hombre +  Updated French strings + +> 2012-06-03 | 2be4bff3f09b | DrSlony +  Updated PDF manual to 4.0.9 + +> 2012-06-03 | 687bf6272b3a | DrSlony +  One more markup fix, this one's in the file deletion dialog, +  rtgui/filecatalog.cc +724-5 + +> 2012-06-03 | 7660fe581dee | DrSlony +  Final update and consistency check of language files and processing +  profiles for 4.0.9 + +> 2012-06-03 | cc280dac0c73 | DrSlony +  Added markup to popups when default raw and non-raw profiles are not +  found + +> 2012-06-03 | f64a4ff5432f | DrSlony +  Fixes markup in Load/save/copy/paste Profile button tooltips, issue +  1388 + +> 2012-06-02 | 99de92c3b1f5 | DrSlony +  Absolute paste of rotation value when using partial paste, issue +  1386 committed on behalf of Dr.Hombre + +> 2012-06-02 | dbf84afb54af | Hombre +  Solving issue 872: "RT file-open/save windows should remember last +  used dir", on behalf of Johannes Wienke + +> 2012-06-02 | df7d6e0cee30 | Hombre +  Patch from issue 1384: "Speedup enhancement of the thumbnails' +  browser" + +> 2012-06-01 | 758d8788f668 | Gyurkó M. 'Dualon' Dávid +  Updated Hungarian translation: enabling it + some minor +  enhancements. + +> 2012-06-01 | f83f1f2d4d11 | Gyurkó M. 'Dualon' Dávid +  Update of Hungarian translation. + +> 2012-06-01 | f34c9eaf01d9 | DrSlony +  Updated the default language file and merged in the corrections, +  then ran generateTranslationDiffs to get the English file and ran +  both through unix2dos to unify line endings. Issue 920 + +> 2012-05-31 | 9388f97ec767 | DrSlony +  Committed Dutch language file on behalf of Willem Termeer and Paul +  Matthijsse, issue 1367 + +> 2012-05-31 | fdaf908f66a8 | Oliver Duis +  LCP engine v3 see issue 1375 + +> 2012-05-29 | 28e942b60ba2 | Joker +  Updated Sony EXIF metadata (added new lenses) + +> 2012-05-28 | 15d96aaa0ed2 | Oliver Duis +  Base color profiles for Nikon D800 and Canon 5D Mark III see issue +  1378 + +> 2012-05-28 | 9404032dd479 | Philip Rinn +  Unify generation of AboutThisBuild.txt and rtgui/version.h. See +  issue 1377. + +> 2012-05-26 | fe160aa7d0a6 | Michael Ezra +  Fix for crash when using "Auto distortion correction" (on behalf of +  lebedev, see issue 1338) + +> 2012-05-25 | 94c0419149e1 | Hombre +  Solving bug reported in issue 1341: "PP3 file cleanup" +  ...application's crash if the default raw or image profile didn't +  exist + +> 2012-05-23 | ea7275d3e647 | Oliver Duis +  LCP engine v2 see issue 1343 + +> 2012-05-20 | 506dd02c3789 | Michael Ezra +  Enhancement: Placement of buttons below the curves (on behalf of +  Wolfgang) see issue 227 (# 47) + +> 2012-05-18 | be1e798c7530 | Oliver Duis +  DCP profile for Nikon D5100 thanks Glacort! + +> 2012-05-18 | c52ab1597ab4 | Oliver Duis +  Fixed compilation issues on Ubuntu Linux see issue 1343 + +> 2012-05-18 | 9c4e2b7c4273 | Oliver Duis +  Two files missing from last commit + +> 2012-05-17 | 0a86d2537c55 | Oliver Duis +  LCP (Lens Correction Profile) support see issue 1343 + +> 2012-05-17 | 6a0b40e2223f | Oliver Duis +  Removed warning for external program support see issue 1365 + +> 2012-05-14 | b30fcbdfaa69 | DrSlony +  Updated the RELEASE_NOTES.txt + +> 2012-05-14 | 6115629f57e4 | Hombre +  Solving issue 607: Auto Crop disabled if Auto Fill off + +> 2012-05-12 | a42648a2f87f | Michael Ezra +  Enhancements: parsing for Leaf exif data & Phase One orientation; +  Fix for Time in reading exif:DateTimeOriginal - REQUIRES CLEARING +  CACHE to take an effect on images prviously viewed in RT; + - on behalf of Torger (issue 766) + +> 2012-05-08 | 9925deee5045 | Emil Martinec +  Minor bugfix for AutoExposure + +> 2012-05-06 | 099cdb136980 | Oliver Duis +  Backed out changeset: 159f9e7014f8 + +> 2012-05-06 | 159f9e7014f8 | Oliver Duis +  Code cleanups on behalf of Lebedev, see issue 1355 + +> 2012-05-05 | eea2f14d863f | Emil Martinec +  Bugfix for autoexposure on blackframes. + +> 2012-05-05 | 957c5df1ac24 | Michael Ezra +  Fix for thumbnail rotation for Leaf, Mamiya and Phase One (Thanks +  Torger!); issue 766 + +> 2012-05-04 | d22bf9288e6c | DrSlony +  Updates and fixes to benchmarkRT + +> 2012-05-02 | 8f7f3036f427 | Oliver Duis +  Fix for Canon 5D Mark III on behalf Lebedev, issue 1347 + +> 2012-05-01 | bfffc520de3e | DrSlony +  PP3 files updated (full) and changes to options.cc, issue 1341 + +> 2012-04-29 | 08ef56d5b65d | DrSlony +  Updated Czech language file on behalf of mkyral, issue 1344. + +> 2012-04-29 | 207d8d272a91 | DrSlony +  Updated German language file on behalf of maweso, issue 1348. + +> 2012-04-26 | 62cefcb38a24 | Oliver Duis +  Nikon D7000 camera color profile in DCP format + +> 2012-04-23 | c13a7add87ba | Oliver Duis +  DCP dual illuminant support see issue 1336 + +> 2012-04-22 | 4ee4f75e86ac | Oliver Duis +  Code cleanups on behalf of Lebedev, see issue 1332 + +> 2012-04-21 | 8a8a15242c21 | Hombre +  The "Blend" HL recovery method was not remembered when modified in +  the Batch Tool Panel editor + +> 2012-04-21 | cc18bd2e902b | Oliver Duis +  Fixed Leaf .mos files wrong orientation and colors on behalf of +  Torger, see issue 1327 + +> 2012-04-21 | 2b0fe3871615 | Oliver Duis +  ICC camera and output profile speedups, cleanup see issue 1329 + +> 2012-04-20 | 704069c8877c | Oliver Duis +  Fixed compilation on 32bit Windows, cleanups see issue 1333 + +> 2012-04-19 | 2db6dae32b17 | Oliver Duis +  Fixed auto profile detection in some cases see issue 1312 + +> 2012-04-16 | ca7c7f52ff04 | Oliver Duis +  Forgot to commit the added files (sorry) + +> 2012-04-16 | 9cab197f142f | Oliver Duis +  External programs plugger see issue 1323 + +> 2012-04-16 | 8e448d936bd7 | Oliver Duis +  Fixed BitsPerSample tag in TIFF output header see issue 1311 + +> 2012-04-14 | 545f45f0e12b | Jacques Desmis +  Fix bug output gamma + +> 2012-04-13 | 0a2016c66e5b | Oliver Duis +  Fixed NoICM would generate incompatible output image see issue 1320 + +> 2012-04-10 | 5569030d30b2 | Oliver Duis +  Fixed two crashes in DCP color engine see issue 1317 + +> 2012-04-09 | 2493dd00b9f3 | Emil Martinec +  Code cleanup for min/max functions. Committed on behalf of +  lebedev.ri (thanks!). + +> 2012-04-07 | 952a99e79816 | Oliver Duis +  Fixed auto DCP detection did not work with some camera makers see +  issue 1312 + +> 2012-04-07 | 766e816228fc | Oliver Duis +  Performance improvements, espc. using monitor profiles see issue +  1310 + +> 2012-04-04 | 273d4edbff73 | Oliver Duis +  Updated Japanese translation on behalf of a3novy, see issue 1302 + +> 2012-04-03 | 03d965613b60 | Michael Ezra +  Fixes for packahed profiles. Addition of neutral-UnchangedTransforms +  profile. + +> 2012-04-03 | be07005cd8ac | Oliver Duis +  Added renamed color profiles (US specific name) + +> 2012-04-02 | 08422f013749 | DrSlony +  Added tag 4.0.8 for changeset 4072ea5c0abd + +> 2012-04-02 | 4072ea5c0abd | DrSlony +  RELEASE_NOTES.txt for RawTherapee-4.0.8 diff --git a/Win32CMakeOptions-Sample.txt b/Win32CMakeOptions-Sample.txt new file mode 100644 index 000000000..54f85d05a --- /dev/null +++ b/Win32CMakeOptions-Sample.txt @@ -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 selectect 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 -mthread -static-libgcc -static-libstdc++ --large-address-aware" 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") 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 b/clean new file mode 100755 index 000000000..5500bf28e --- /dev/null +++ b/clean @@ -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/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/RawTherapeeManual_en.pdf b/doc/RawTherapeeManual_en.pdf new file mode 100644 index 000000000..ec91f6932 Binary files /dev/null and b/doc/RawTherapeeManual_en.pdf differ diff --git a/doc/manpage/rawtherapee.1 b/doc/manpage/rawtherapee.1 new file mode 100644 index 000000000..423c3bc47 --- /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/languagePack.nsi b/languagePack.nsi new file mode 100644 index 000000000..e9e6af5e6 --- /dev/null +++ b/languagePack.nsi @@ -0,0 +1,126 @@ +; RawTherapee Language Pack +; +; Installes just the language file in an existing RawTherapee installation. +; +;------------------------------------------------------------------------------ +; Name, Outputfile and Version information +;------------------------------------------------------------------------------ + +; **** start edit section: please adapt below options per language pack release **** +; The name of the installer +Name "RT 2.4.1 - language Pack" + +; The file to write +OutFile "RT241-langPack-20091018.exe" + +LoadLanguageFile "${NSISDIR}\Contrib\Language files\English.nlf" + + VIProductVersion "2.4.1.0" + VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductName" "RawTherapee Language Pack" + VIAddVersionKey /LANG=${LANG_ENGLISH} "LegalCopyright" " Raw Therapee" + VIAddVersionKey /LANG=${LANG_ENGLISH} "FileDescription" "Language Pack RawTherapee 2.4.1" + VIAddVersionKey /LANG=${LANG_ENGLISH} "FileVersion" "2.4.1-2009-10-18" + VIAddVersionKey /LANG=${LANG_ENGLISH} "Comments" "Compatible also for RT2.4 and RT2.3" +; VIAddVersionKey /LANG=${LANG_ENGLISH} "CompanyName" "Fake company" +; VIAddVersionKey /LANG=${LANG_ENGLISH} "LegalTrademarks" "Test Application is a trademark of Fake company" + +; **** end edit section: no changes needed per release below **** + +;------------------------------------------------------------------------------ +; Installation Directory, Dialog box for +;------------------------------------------------------------------------------ + + +; The default installation directory +InstallDir "$PROGRAMFILES\Raw Therapee\languages" +DirText "The Language Pack has to be installed into the RawTherapee installation directory, into the language subdirectory." \ + "RawTherapee Installation Directory" \ + "" \ + "Please select the installation Directory of RawTherapee:" + +;PageEx directory +; DirVerify leave +; PageCallbacks "" "" dirLeave +;PageExEnd + +; Registry key to check for directory (so if you install again, it will +; overwrite the old one automatically) +InstallDirRegKey HKCU "Software\Raw Therapee" "" + +;------------------------------------------------------------------------------ +; Installation Rights (Vista only) +;------------------------------------------------------------------------------ + +; Request application privileges for Windows Vista +RequestExecutionLevel admin + + +;------------------------------------------------------------------------------ +; Pages: +;------------------------------------------------------------------------------ + +; Pages + +;Page components +Page directory +Page instfiles + +;UninstPage uninstConfirm +;UninstPage instfiles + +;------------------------------------------------------------------------------ +; Sections: stuff to be installed +;------------------------------------------------------------------------------ + +; The stuff to install +Section "RawTherapee Language Pack (required)" + + SectionIn RO + + ifFileExists $INSTDIR\languages\*.* 0 +3 + SetOutPath $INSTDIR\languages + Goto +2 + SetOutPath $INSTDIR + + ; Set output path to the installation directory. + ;SetOutPath $INSTDIR + + ; Put file there + File "release\languages\*" + + ; Write the installation path into the registry + ;WriteRegStr HKLM SOFTWARE\NSIS_Example2 "Install_Dir" "$INSTDIR" + + ; Write the uninstall keys for Windows + ;WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Example2" "DisplayName" "NSIS Example2" + ;WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Example2" "UninstallString" '"$INSTDIR\uninstall.exe"' + ;WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Example2" "NoModify" 1 + ;WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Example2" "NoRepair" 1 + ;WriteUninstaller "uninstall.exe" + +SectionEnd + +;------------------------------------------------------------------------------ +; Uninstaller: not needed here +;------------------------------------------------------------------------------ + +; Uninstaller + +;Section "Uninstall" + + ; Remove registry keys +; DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Example2" +; DeleteRegKey HKLM SOFTWARE\NSIS_Example2 + + ; Remove files and uninstaller +; Delete $INSTDIR\example2.nsi +; Delete $INSTDIR\uninstall.exe + + ; Remove shortcuts, if any +; Delete "$SMPROGRAMS\Example2\*.*" + + ; Remove directories used +; RMDir "$SMPROGRAMS\Example2" +; RMDir "$INSTDIR" + +;SectionEnd 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..26687e1c0 --- /dev/null +++ b/rtdata/CMakeLists.txt @@ -0,0 +1,41 @@ + +file (GLOB PROFILEFILES "profiles/*.pp3") +file (GLOB LANGUAGEFILES "languages/*") +file (GLOB SOUNDFILES "sounds/*") +file (GLOB INPUTICCFILES "iccprofiles/input/*") +file (GLOB OUTPUTICCFILES "iccprofiles/output/*") +file (GLOB DCPFILES "dcpprofiles/*") +# 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 (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 ${PROFILEFILES} DESTINATION "${DATADIR}/profiles") +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 ${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) 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/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/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 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..9df11b375 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..9bb1c934a 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..b3e1fedf6 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..0d1a0e182 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..c9f36792f 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..2dfac235b 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..6a70a2653 --- /dev/null +++ b/rtdata/icons/mime-types @@ -0,0 +1,32 @@ +# 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-tif; +inode/directory; diff --git a/rtdata/icons/rawtherapee.desktop.in b/rtdata/icons/rawtherapee.desktop.in new file mode 100644 index 000000000..b90c75118 --- /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-tif; +Categories=Photography;Graphics;2DGraphics;RasterGraphics;GTK; diff --git a/rtdata/images/Chanmixer-BB.png b/rtdata/images/Chanmixer-BB.png new file mode 100644 index 000000000..269dc7d33 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..9ab910f49 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..9453847af Binary files /dev/null and b/rtdata/images/Chanmixer-BR.png differ diff --git a/rtdata/images/Chanmixer-GB.png b/rtdata/images/Chanmixer-GB.png new file mode 100644 index 000000000..759461f59 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..b4b2a7deb 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..32e17f4cc Binary files /dev/null and b/rtdata/images/Chanmixer-GR.png differ diff --git a/rtdata/images/Chanmixer-RB.png b/rtdata/images/Chanmixer-RB.png new file mode 100644 index 000000000..65c2be1ac 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..d00e8ba65 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..3e9a3aa7a Binary files /dev/null and b/rtdata/images/Chanmixer-RR.png differ diff --git a/rtdata/images/Dark/actions/PanelEnding.png b/rtdata/images/Dark/actions/PanelEnding.png new file mode 100644 index 000000000..f5e433ec8 Binary files /dev/null and b/rtdata/images/Dark/actions/PanelEnding.png differ diff --git a/rtdata/images/Dark/actions/beforeafter.png b/rtdata/images/Dark/actions/beforeafter.png new file mode 100644 index 000000000..8721c9b1f 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..67f01f368 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..1fb1e5de9 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..80d88a28a 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..685a7e07b 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..153f13ca2 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..44f481668 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..efd5a8439 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..d10295706 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..6e6f12772 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..f8bd43df3 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..e7b9d3431 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..118db16f8 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..b5424f116 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..fb3358d60 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..25167c431 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..377e46328 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..5f4637c81 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..4d461073b 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..0aacd0d8f 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..8bfb91bf3 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..c9152f5b8 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..a16373276 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..5c4808eee 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..10d1941a5 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..a82ef56b6 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..55e26d67d 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..fd960426a Binary files /dev/null and b/rtdata/images/Dark/actions/distortion-auto.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..d7703c333 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..2aa5559ed 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..73158bd9d 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..c842e5b09 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..6cf614faf 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..26a1543cf 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..9ec5745df 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..cdac01f09 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..75ffcbb91 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..d6cb79758 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..57f26f3e1 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..be23c0a0e 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..68910b856 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..573adc753 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..3126a5caa 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..2785a66f6 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..12bd431f3 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..1daa96953 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..6eb643e3b 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..816ddce93 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..6eb643e3b 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..fe75bfde2 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..00cd2293a 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..73158bd9d 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..59b5a056e 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..c842e5b09 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..bbb1f6598 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..3d1b2cfa7 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..1daa96953 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..2aa5559ed 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..6cf614faf 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..7c937c491 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..fd276003f 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..eac1cae35 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..25a28f9be 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..4a849945c 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..8bda89e1c 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..b1b37911f 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..660b21516 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..365de5288 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..0ece21ca2 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..188f4ad9c 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..07845cee0 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..37f300e3c 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..b606b825e 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..afb574938 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..44a51f117 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..40b37f824 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..69567180c Binary files /dev/null and b/rtdata/images/Dark/actions/histBlueg.png differ diff --git a/rtdata/images/Dark/actions/histFull.png b/rtdata/images/Dark/actions/histFull.png new file mode 100644 index 000000000..dac93821a 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..a8845fc40 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..09c7c1149 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..39ab3e558 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..56c90c446 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..ea8838072 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..1b7ad6706 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..c46e4b38f 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..a40fdd8af 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..9167bdd2e 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..7c2d574da 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..72475541a 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..584b8f9e7 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..12bd431f3 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..1854b7f51 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..fd276003f 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..1712b42e3 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..22b4db184 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..a9891cbfd 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..6c03752f4 Binary files /dev/null and b/rtdata/images/Dark/actions/meta.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..fa600b466 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..0d22a1799 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..62dbc86d2 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..83654c0c1 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..00fde6ca1 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..3a2263689 Binary files /dev/null and b/rtdata/images/Dark/actions/panel-to-top.png differ diff --git a/rtdata/images/Dark/actions/popuparrow.png b/rtdata/images/Dark/actions/popuparrow.png new file mode 100644 index 000000000..118ddef79 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..35e5ecaf7 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..753f2c616 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..d59363703 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..06f12ef93 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..77dce6dc9 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..451c1fa46 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..4eac31180 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..8a6ad5903 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..603d4f4c6 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..04f1dfd14 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..7a0ae85a7 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..1b9fbba68 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..05cda1bb4 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..82cfc0ca7 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..55b2a1b45 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..c915d7c9c 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..39c6f5063 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..3b0d36338 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..bcbfdf5fe 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..85ffcdcd6 Binary files /dev/null and b/rtdata/images/Dark/actions/processing.png differ diff --git a/rtdata/images/Dark/actions/rated.png b/rtdata/images/Dark/actions/rated.png new file mode 100644 index 000000000..43f47b457 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..8b86fb2f7 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..01fc73c72 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..ecc8886d5 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..c60a9def6 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..92e4c3d33 Binary files /dev/null and b/rtdata/images/Dark/actions/refresh-white.png differ diff --git a/rtdata/images/Dark/actions/rtwindow.png b/rtdata/images/Dark/actions/rtwindow.png new file mode 100644 index 000000000..bc0aa82c4 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..ba600ad25 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..954ba7dde 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..711502d62 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..161f30da2 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..bd2389c88 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..2993b96ec 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..2c3ffcab5 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..5d761bbbf 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..7e9348ab4 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..87aaf07ba 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..3e1a55005 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..9e062a7cf 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..87aaf07ba 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..dea361d9d 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..cd17c41c0 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..cd17c41c0 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..dea361d9d 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..ffeb32eeb 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..20d90cbcd 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..d044bdf82 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..f349007f7 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..45a2c6f12 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..90fbb0059 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..5678dc496 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..9294a3fcb 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..c07f3b36c 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..5d5f9c593 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..ffdb5fbb7 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..17dc495b2 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..fe388c48d Binary files /dev/null and b/rtdata/images/Dark/actions/wb-tungsten.png differ diff --git a/rtdata/images/Dark/devices/computer.png b/rtdata/images/Dark/devices/computer.png new file mode 100644 index 000000000..13895d772 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..13895d772 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..09babc056 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..3381c5a9b 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..09babc056 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..13895d772 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..3381c5a9b 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..09babc056 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..09babc056 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..09babc056 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..13895d772 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..66c83e0b3 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..66c83e0b3 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..4b3e7ab6d 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..8e1e020be Binary files /dev/null and b/rtdata/images/Dark/places/user-home.png differ diff --git a/rtdata/images/Light/actions/PanelEnding.png b/rtdata/images/Light/actions/PanelEnding.png new file mode 100644 index 000000000..068739ec4 Binary files /dev/null and b/rtdata/images/Light/actions/PanelEnding.png differ diff --git a/rtdata/images/Light/actions/beforeafter.png b/rtdata/images/Light/actions/beforeafter.png new file mode 100644 index 000000000..e847740c6 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..502d3f7c5 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..1fb1e5de9 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..80d88a28a 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..685a7e07b 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..153f13ca2 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..44f481668 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..89eadcbc8 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..e36da1a02 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..20210036c 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..b5b165630 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..42608a90c 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..50a66cc8e 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..14f9c0312 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..0217886e7 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..1459d0a62 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..6e072b84f 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..7938b05a3 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..d80f9d2cd 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..8481cb2f2 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..542be38c3 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..6f217ebf3 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..9031b2dd6 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..bd514ec41 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..b140f79fd 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..2a06e090c 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..0e2bf6f86 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..05bd12f65 Binary files /dev/null and b/rtdata/images/Light/actions/distortion-auto.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..5b2987b01 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..0fa283169 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..81e6a0819 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..39fa7333f 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..2a08c13a1 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..26a1543cf 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..9ec5745df 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..cdac01f09 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..75ffcbb91 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..d6cb79758 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..37c2e903d 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..11bfb7e68 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..b71e20c7c 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..f5d9fa661 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..b187988fa 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..34431f064 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..8ab0fa042 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..02f1e1620 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..39b1aada8 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..35ad19442 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..39b1aada8 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..c5ed65a99 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..9ab6fa21b 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..81e6a0819 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..ae8f3c264 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..39fa7333f 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..54180db5f 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..f621dbdf8 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..02f1e1620 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..0fa283169 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..2a08c13a1 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..91dac7deb 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..ccf991e57 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..d7c1d6e9a 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..5cbb75e2c 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..4734c27da 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..11711b2a3 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..4a1718425 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..b051a2ff4 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..9c44be5bd 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..fc930ed5f 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..fd5857b88 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..48c63dfa6 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..14032f327 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..2daa34e5a 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..2e88e6c1c 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..4139cd3c0 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..40b37f824 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..69567180c Binary files /dev/null and b/rtdata/images/Light/actions/histBlueg.png differ diff --git a/rtdata/images/Light/actions/histFull.png b/rtdata/images/Light/actions/histFull.png new file mode 100644 index 000000000..67cac5e60 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..dc36272da 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..09c7c1149 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..39ab3e558 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..56c90c446 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..ea8838072 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..1b7ad6706 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..c46e4b38f 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..f30f35a7b 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..b9583e4de 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..82d8c8cc7 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..5531c9c75 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..f9c901b91 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..8ab0fa042 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..5e94b6f35 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..ccf991e57 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..1653e1426 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..29b56c434 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..f321e5e13 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..24fe1ec42 Binary files /dev/null and b/rtdata/images/Light/actions/meta.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..88ab832ed 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..c9e15de87 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..0aabf8e4f 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..09ca9bb25 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..452637998 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..f28ed2a48 Binary files /dev/null and b/rtdata/images/Light/actions/panel-to-top.png differ diff --git a/rtdata/images/Light/actions/popuparrow.png b/rtdata/images/Light/actions/popuparrow.png new file mode 100644 index 000000000..376eb2312 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..35e5ecaf7 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..753f2c616 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..d59363703 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..06f12ef93 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..77dce6dc9 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..451c1fa46 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..4eac31180 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..8a6ad5903 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..4fcd4288d 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..2a6a73685 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..7a0ae85a7 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..1b9fbba68 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..05cda1bb4 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..82cfc0ca7 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..55b2a1b45 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..c915d7c9c 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..055ad232c 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..89a24dc09 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..9b5a057f9 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..755cce606 Binary files /dev/null and b/rtdata/images/Light/actions/processing.png differ diff --git a/rtdata/images/Light/actions/rated.png b/rtdata/images/Light/actions/rated.png new file mode 100644 index 000000000..55f82c751 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..b74dcc19e 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..a271a2e6a 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..f6aa838fa 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..0f4bdcbea 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..259974b3a Binary files /dev/null and b/rtdata/images/Light/actions/refresh-white.png differ diff --git a/rtdata/images/Light/actions/rtwindow.png b/rtdata/images/Light/actions/rtwindow.png new file mode 100644 index 000000000..7a4bbd6a1 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..0fb57ae5a 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..b9dd9bbaa 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..9fe33ef72 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..87a3f506a 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..ec9d958ca 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..15e073be5 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..fb9534aa8 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..88f437f76 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..70a0f5e59 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..e1e5cc10a 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..ebf86b933 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..d0a7aa19b 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..e1e5cc10a 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..f004c8e84 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..2b5a6203c 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..2b5a6203c 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..f004c8e84 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..438d2157c 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..4b02cb118 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..2decab69d 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..088a00d39 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..0271e9783 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..020971e9d 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..98d055fd2 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..7b18e38e7 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..31b124269 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..d1f7f0552 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..17b98bb83 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..8d08df721 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..646db7706 Binary files /dev/null and b/rtdata/images/Light/actions/wb-tungsten.png differ diff --git a/rtdata/images/Light/devices/computer.png b/rtdata/images/Light/devices/computer.png new file mode 100644 index 000000000..45589ad74 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..45589ad74 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..c0f68bcb6 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..6ce1d20ae 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..c0f68bcb6 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..45589ad74 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..6ce1d20ae 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..c0f68bcb6 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..c0f68bcb6 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..c0f68bcb6 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..45589ad74 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..ad31e8d1d 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..ad31e8d1d 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..a1f604de2 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..c4578b776 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..ad8998178 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..ed434aa36 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..6199711a1 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..e1b20bd04 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..c78a09936 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..bd19d2fff 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..01861c210 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..12d1ed202 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..e7f5c457c 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..693a12d5e 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..c0c8a1666 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..908144636 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..7f5e87785 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..44e4f5acb 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..d4b275d2d 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..2681422ae 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..95ffc97e3 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..f250cc44f 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..94d5fbdd5 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..a5f90bf30 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..81d78b517 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..c32da3a05 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..3a746c534 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..3b0ef7946 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..4d2d0a7d3 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..794f6142c 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..e89930a77 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..d888b458c 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..d888b458c 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..116e21a86 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..45a49beca 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..3b687133c 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..f38fd20de 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..1239726f8 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..263050446 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..2db9297e5 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..b9034194f 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..9bcf20258 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..5efefb92b 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..cc2fdbd58 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..98b81b9b5 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..c00eb2c48 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..2aeab4f80 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..6ae9c498c 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..36951d6d1 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..1aa7f095c 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..3241084e4 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..1d9182ae8 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..52f58630f 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..7c4e1b14b 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..0fc37701b 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..d6e35020d 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..98dc3a769 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..b0c8a48d7 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..6e847015f 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..56cc85f52 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..340434d5e 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..92dddd2ea 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..adbf7f3a2 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..6b1b94336 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..ddc1eb136 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..b152f7e8c 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..4abcbb226 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..d6bb4188a 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..a597b5ade 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..9af98926b 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..a298bc926 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..e57f56fe1 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..0623ccbe5 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..cdca72893 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..dc12f415d 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..00b654e8c 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..96c1a6da4 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..3e3cf12db 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..811e2cbeb 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..78b856c58 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..f8bc2a1e7 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..7fcdf8e46 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..420d3a963 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..841f02586 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..1eab0d9b3 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..8c4e27595 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..a887ec40f 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..ae21857ec 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..bd82fdd5e 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..235c4a7f5 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..5fef46151 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..77f6aa86e 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..33e8c4ed7 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..4f5e3fd3c 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..1b03db8fd 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..3d6bff4f6 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..77e98711d 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..556a93fb5 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..a1d99ee41 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..20b0809ae 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..835344479 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..91aa647bf 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..abe097d00 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..0528ea05c 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..90ca8b433 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..13234db94 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..5b9400b13 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..3c5e42eda 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..92f68899c 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..80be870dc 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..51e6b68ef 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..06ed43f2b 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..9b07b6234 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..d49225579 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..0550d058c 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..afff31530 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..c185c78e4 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..88f473a2b 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..c185c78e4 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..44b4021a9 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..17f7c62f0 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..3d6bff4f6 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..a8d8cfcdd 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..a7fcfe1df 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..fd1605cbf --- /dev/null +++ b/rtdata/languages/Catala @@ -0,0 +1,1223 @@ +ABOUT_TAB_BUILD;Versió +ABOUT_TAB_CREDITS;Crèdits +ABOUT_TAB_LICENSE;Llicència +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_DIALOGLABEL;Filtre Exif +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 +FILEBROWSER_ADDDELTEMPLATE;Afeg/Treu plantilles... +FILEBROWSER_APPLYPROFILE;Aplica perfil +FILEBROWSER_ARRANGEMENTHINT;Canvia entre alineació vertical/horitzontal de les minifotos +FILEBROWSER_AUTODARKFRAME;Auto marc fosc +FILEBROWSER_AUTOFLATFIELD;Auto camp pla +FILEBROWSER_BROWSEPATHBUTTONHINT;Clic per navegar al path escollit +FILEBROWSER_BROWSEPATHHINT;Posa path on buscar (Ctrl-o set focus,Ctrl-Enter navegar amb gestor d'arxius);nPath dreceres: ~ - directori d'usuari, ! - carpeta de fotos de l'usuari +FILEBROWSER_CACHECLEARFROMFULL;Esborra el cau - tot +FILEBROWSER_CACHECLEARFROMPARTIAL;Esborra el cau - part +FILEBROWSER_CACHE;Cau +FILEBROWSER_CLEARPROFILE;Treu perfil +FILEBROWSER_COPYPROFILE;Copia perfil +FILEBROWSER_CURRENT_NAME;Nom actual: +FILEBROWSER_DARKFRAME;Marc fosc +FILEBROWSER_DELETEDLGLABEL;Confirmació d'esborrar fitxer +FILEBROWSER_DELETEDLGMSGINCLPROC;Segur que voleu suprimir els %1 seleccionats INCLOENT la versió processada? +FILEBROWSER_DELETEDLGMSG;Segur que voleu esborrar els %1 fitxers? +FILEBROWSER_EMPTYTRASHHINT;Buida permanentment la paperera +FILEBROWSER_EMPTYTRASH;Buida paperera +FILEBROWSER_EXIFFILTERAPPLYHINT;Commuta on/off el filtre exif del gestor de fitxers +FILEBROWSER_EXIFFILTERAPPLY;Aplica +FILEBROWSER_EXIFFILTERLABEL;Filtre Exif +FILEBROWSER_EXIFFILTERSETTINGSHINT;Canvia ajustos del filtre Exif +FILEBROWSER_EXIFFILTERSETTINGS;Ajustos +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_PARTIALPASTEPROFILE;Enganxa al perfil parcialment +FILEBROWSER_PASTEPROFILE;Enganxa perfil +FILEBROWSER_POPUPCANCELJOB;Cancel·la treball +FILEBROWSER_POPUPCOPYTO;Copia a... +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_POPUPPROCESS;Posa a la cua de processos +FILEBROWSER_POPUPRANK1;Rang 1 +FILEBROWSER_POPUPRANK2;Rang 2 +FILEBROWSER_POPUPRANK3;Rang 3 +FILEBROWSER_POPUPRANK4;Rang 4 +FILEBROWSER_POPUPRANK5;Rang 5 +FILEBROWSER_POPUPREMOVEINCLPROC;Treu del sist. de fitxers & process. en curs +FILEBROWSER_POPUPREMOVESUBMENU;Suprimeix +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_PROCESSINGSETTINGSHINT;Indica format de fitxer i directori de sortida +FILEBROWSER_PROCESSINGSETTINGS;Ajustos +FILEBROWSER_RENAMEDLGLABEL;Reanomena fitxer +FILEBROWSER_RENAMEDLGMSG;Reanomena fitxer "%1" a: +FILEBROWSER_SELECTDARKFRAME;Selecc. marc fosc... +FILEBROWSER_SELECTFLATFIELD;Selecc. camp pla... +FILEBROWSER_SHOWDIRHINT;Exposa totes les imatges del directori +FILEBROWSER_SHOWEXIFINFO;Mostra dades EXIF i +FILEBROWSER_SHOWQUEUEHINT;Ensenya el contingut de la cua de procés +FILEBROWSER_SHOWRANK1HINT;Exposa imatges d' 1 estrella +FILEBROWSER_SHOWRANK2HINT;Exposa imatges de 2 estrelles +FILEBROWSER_SHOWRANK3HINT;Exposa imatges de 3 estrelles +FILEBROWSER_SHOWRANK4HINT;Exposa imatges de 4 estrelles +FILEBROWSER_SHOWRANK5HINT;Exposa imatges de 5 estrelles +FILEBROWSER_SHOWTRASHHINT;Veure què hi ha a la paperera +FILEBROWSER_SHOWUNRANKHINT;Mostra imatges sense rang +FILEBROWSER_STARTPROCESSINGHINT;Inicia processar/desar d'imatges de la cua +FILEBROWSER_STARTPROCESSING;Inicia procés +FILEBROWSER_STOPPROCESSINGHINT;Atura processament d'imatges +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 +FILEBROWSER_ZOOMOUTHINT;Reduïr minifoto +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_HIGH_QUALITY;Alta qualitat +GENERAL_LANDSCAPE;Horitzontal +GENERAL_LOAD;Carrega +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_YES;Sí +HISTOGRAM_BUTTON_B;B +HISTOGRAM_BUTTON_G;G +HISTOGRAM_BUTTON_L;L +HISTOGRAM_BUTTON_RAW;Raw +HISTOGRAM_BUTTON_R;R +HISTOGRAM_LABEL;Histograma +HISTOGRAM_TOOLTIP_B;Ensenya/amaga l'histograma BLAU +HISTOGRAM_TOOLTIP_G;Ensenya/amaga l'histograma VERD +HISTOGRAM_TOOLTIP_L;Ensenya/amaga l'histograma de luminància CIELAB +HISTOGRAM_TOOLTIP_RAW;Mostra/Amaga l'histograma RAW +HISTOGRAM_TOOLTIP_R;Ensenya/amaga l'histograma VERMELL +HISTORY_CHANGED;Canviat +HISTORY_CUSTOMCURVE;Corba particular +HISTORY_DELSNAPSHOT;Treu instant. +HISTORY_FROMCLIPBOARD;Del portapapers +HISTORY_LABEL;Història +HISTORY_MSG_1;Imatge oberta +HISTORY_MSG_2;Perfil carregat +HISTORY_MSG_3;Perfil 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 +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 intensos +HISTORY_MSG_18;Luminància: Compressió de foscos +HISTORY_MSG_19;Corba de luminància +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;Evitar pèrdua de color +HISTORY_MSG_35;Saturació: limitador +HISTORY_MSG_36;Saturació límit +HISTORY_MSG_37;Augment de color +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;Canvi color "A" +HISTORY_MSG_42;Canvi color "B" +HISTORY_MSG_43;Dessorollant luminància +HISTORY_MSG_44;Lumin. dessoroll Radi +HISTORY_MSG_45;Lumin. dessoroll, tolerància vores +HISTORY_MSG_46;Dessorollant color +HISTORY_MSG_47;Dessoroll de color: Radi +HISTORY_MSG_48;Dessoroll de color: Tolerància vores +HISTORY_MSG_49;Dessoroll de color, sensib. de vores +HISTORY_MSG_50;Eina de foscos/clars intensos +HISTORY_MSG_51;Augment de clars +HISTORY_MSG_52;Augment de 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;Rotació +HISTORY_MSG_62;Correcció distorsió de l'objectiu +HISTORY_MSG_63;Instantània seleccionada +HISTORY_MSG_64;Retalla 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;Coeficients d'ónula +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;Saturació +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;Limitador de saturació +HISTORY_MSG_113;Saturació límit +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;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. HL preservant expos. +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_NEWSNAPSHOTAS;Com... +HISTORY_NEWSNAPSHOT;Afegeix +HISTORY_NEWSSDIALOGLABEL;Etiqueta d'instantània: +HISTORY_NEWSSDIALOGTITLE;Afegir instant. +HISTORY_SETTO;Fixat a +HISTORY_SNAPSHOTS;Instantànies +HISTORY_SNAPSHOT;Instantània +ICMPANEL_FILEDLGFILTERANY;Tots els fitxers +ICMPANEL_FILEDLGFILTERICM;Fitxers de perfils ICC +ICMPANEL_GAMMABEFOREINPUT;El perfil aplica Gamma +ICMPANEL_INPUTCAMERA;Propi de la càmera +ICMPANEL_INPUTCUSTOM;Especial +ICMPANEL_INPUTDLGLABEL;Selecc. perfil ICC d'entrada... +ICMPANEL_INPUTEMBEDDED;Usar l'encastat si és possible +ICMPANEL_INPUTPROFILE;Perfil d'entrada +ICMPANEL_NOICM;No cap ICM: Sortida sRGB +ICMPANEL_OUTPUTDLGLABEL;Selecc. perfil ICC de sortida... +ICMPANEL_OUTPUTPROFILE;Perfil de sortida +ICMPANEL_SAVEREFERENCE;Desa com a imatge de ref. als perfils +ICMPANEL_WORKINGPROFILE;Perfil de treball +IMAGEAREA_DETAILVIEW;Vista de detall +IPTCPANEL_AUTHORHINT;Nom del creador de l'objecte, p.e. escriptor, fotògraf o artista gràfic (By-line). +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_EXIT;Sortida +MAIN_BUTTON_FULLSCREEN;Pantalla sencera +MAIN_BUTTON_PREFERENCES;Preferències +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Afeg. imatge actual a la cua de procés Ctrl+Q +MAIN_BUTTON_QUEUE;Posa a la cua +MAIN_BUTTON_SAVEAS;Com... +MAIN_BUTTON_SAVE;Desa la imatge +MAIN_BUTTON_SAVE_TOOLTIP;Desa imatge actual Ctrl+S +MAIN_BUTTON_SENDTOEDITOR;Envia a l'editor +MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Edita la imatge actual a un editor extern Ctrl+E +MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Mostra/amaga panells laterals m +MAIN_BUTTON_UNFULLSCREEN;Fi pantalla sencera +MAIN_FRAME_BATCHQUEUE;Cua de procés +MAIN_FRAME_BATCHQUEUE_TOOLTIP; Cua de procés Ctrl-F3 +MAIN_FRAME_EDITOR;Editor +MAIN_FRAME_EDITOR_TOOLTIP; Editor Ctrl-F4 +MAIN_FRAME_FILEBROWSER;Gestor de fitxers +MAIN_FRAME_FILEBROWSER_TOOLTIP; Gestor de fitxers 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 puc carregar la imatge +MAIN_MSG_CANNOTSAVE;Error desant el fitxer +MAIN_MSG_CANNOTSTARTEDITOR;No puc iniciar l'editor +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Poseu el path correcte en el diàleg "Preferències". +MAIN_MSG_ERRORDURINGIMAGESAVING;Error en desar la imatge +MAIN_MSG_EXITJOBSINQUEUEINFO;Les imatges no processades de la cua es perdran en sortir. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Segur que voleu sortir? Hi ha imatges no processades a la cua. +MAIN_MSG_JOBSINQUEUE;Treball(s) a la cua. +MAIN_MSG_NAVIGATOR;Navegador +MAIN_MSG_PLACES;Llocs +MAIN_MSG_QOVERWRITE;El voleu sobreescriure? +MAIN_TAB_BASIC;Bàsic +MAIN_TAB_COLOR;Color +MAIN_TAB_COLOR_TOOLTIP;Alt-c +MAIN_TAB_DETAIL;Detall +MAIN_TAB_DETAIL_TOOLTIP;Alt-d +MAIN_TAB_DEVELOP;Desenv. +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Exposició +MAIN_TAB_EXPOSURE_TOOLTIP;Alt-e +MAIN_TAB_FILTER;Filtre +MAIN_TAB_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadades +MAIN_TAB_METADATA_TOOLTIP;Alt-m +MAIN_TAB_RAW;RAW +MAIN_TAB_RAW_TOOLTIP;Alt-r +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;Forma +MAIN_TAB_TRANSFORM_TOOLTIP;Alt-t +MAIN_TOGGLE_BEFORE_AFTER;B|A +MAIN_TOOLTIP_HIDEFP;Mostra/amaga panell inferior (directori i gestor de fitxers, tecla: F) +MAIN_TOOLTIP_HIDEHP;Mostra/amaga panell esquerre (incloent la història, tecla: H) +MAIN_TOOLTIP_INDCLIPPEDH;Indicador de pèrdues en clars +MAIN_TOOLTIP_INDCLIPPEDS;Indicador de pèrdues en foscos +MAIN_TOOLTIP_PREFERENCES;Fixa preferències +MAIN_TOOLTIP_QINFO;Info breu de la imatge +MAIN_TOOLTIP_SAVEAS;Desa la imatge en directori escollit +MAIN_TOOLTIP_SAVE;Desa la imatge al directori per defecte +MAIN_TOOLTIP_SHOWHIDELP1;Mostra/amaga panell esquerre l +MAIN_TOOLTIP_SHOWHIDERP1;Mostra/amaga panell dret Alt-l +MAIN_TOOLTIP_SHOWHIDETP1;Mostra/amaga panell superior Shift-l +MAIN_TOOLTIP_TOGGLE;Alterna vista abans/despré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_NA;x = n/a, y = n/a +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_COLORBOOST;Augment de color +PARTIALPASTE_COLORDENOISE;Dessorollar color +PARTIALPASTE_COLORGROUP;Ajustos de color +PARTIALPASTE_COLORMIXER;Barrejador de color +PARTIALPASTE_COLORSHIFT;Canvi de color +PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto-omple +PARTIALPASTE_COMPOSITIONGROUP;Ajustos de composició +PARTIALPASTE_CROP;Retalla +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_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_HLRECONSTRUCTION;Reconstrucc. clars intensos +PARTIALPASTE_HLRECOVERYAMOUNT;Quant. recup. clars intensos +PARTIALPASTE_HLRECOVERYTHRESHOLD;Llindar recup. clars intensos +PARTIALPASTE_HLRECOVERY;Recup. de clars intensos +PARTIALPASTE_HSVEQUALIZER;Equalitzador HSV +PARTIALPASTE_ICMSETTINGS;Ajustos ICM +PARTIALPASTE_IMPULSEDENOISE;Impuls de reducció de soroll +PARTIALPASTE_IPTCINFO;Dades IPTC +PARTIALPASTE_LABCURVE;Ajustos Lab +PARTIALPASTE_LENSGROUP;Ajustos de l'objectiu +PARTIALPASTE_LUMACURVE;Corba de luminància +PARTIALPASTE_LUMADENOISE;Reducció de soroll de luminància +PARTIALPASTE_LUMINANCEGROUP;Ajustos de luminància +PARTIALPASTE_METAICMGROUP;Ajustos Metadades/ICM +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_LINEAR;Punt blanc raw corr. factor linear +PARTIALPASTE_RAWEXPOS_PRESER;Corr. punt blanc raw preservant HL (EV) +PARTIALPASTE_RAWGROUP;Ajustos raw +PARTIALPASTE_RAW_DCBENHANCE;Aplica pas de millora DCB +PARTIALPASTE_RAW_DCBITERATIONS;Nombre d'iteracions DCB +PARTIALPASTE_RAW_DMETHOD;Mètode demosaicat +PARTIALPASTE_RAW_FALSECOLOR;Passos de supressió de fals color demosaicant +PARTIALPASTE_RESIZE;Canviar tamany +PARTIALPASTE_ROTATION;Rotació +PARTIALPASTE_SHADOWSHIGHLIGHTS;Foscos/clars intensos +PARTIALPASTE_SHARPENING;Enfocant +PARTIALPASTE_VIGNETTING;Correcció del vorafosc +PARTIALPASTE_WAVELETEQUALIZER;Equalitzador d'ónula +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_CACHESTRAT1;Preferir rapidesa a baix ús de memòria +PREFERENCES_CACHESTRAT2;Preferir baix ús de memòria a rapidesa +PREFERENCES_CACHESTRAT;Estratègia del cau +PREFERENCES_CACHETHUMBFORM;Format del cau en minifoto +PREFERENCES_CACHETHUMBHEIGHT;Màxima alçada de minifoto +PREFERENCES_CLEARDLG_LINE1;Esborrant el cau +PREFERENCES_CLEARDLG_LINE2;Això pot tardar alguns segons +PREFERENCES_CLEARDLG_TITLE;Espereu.. +PREFERENCES_CLIPPINGIND;Indicador de pèrdues +PREFERENCES_CMETRICINTENT;Intent colorimètric +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_DEMOSAICINGALGO;Algoritme de demosaicat +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 gestor d'arxius +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 fitxers d'imatge +PREFERENCES_FORRAW;Per fitxers RAW +PREFERENCES_GIMPPATH;Directori d'instal. del GIMP +PREFERENCES_GTKTHEME;GTK predeterminat +PREFERENCES_HINT;Consell +PREFERENCES_HLTHRESHOLD;Llindar pèrdues en clars +PREFERENCES_ICCDIR;Directori dels perfils ICC +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 minifoto RAW interna si no està editada +PREFERENCES_LIVETHUMBNAILS;Minifotos vives (lent) +PREFERENCES_METADATA;Metadata +PREFERENCES_MONITORICC;Perfil 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_OUTDIRHINT;Podeu usar les següents cadenes de format:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nAquestes cadenes de format refereixen als directoris i sub-paths del path del fitxer RAW.\n\nPer exemple, si /home/tom/image/02-09-2006/dsc0012.nef ha estat obert, el significat de les cadenes de format és:\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 voleu desar la imatge actual on hi ha l'original, escriviu:\n%p1/%f\n\nSi voleu desar la imatge actual en el directori 'refetes' dins el directori on hi ha l'original, escriviu:\n%p1/refetes/%f\n\nSi voleu desar la imatge actual en el directori '/home/tom/refetes' conservant el mateix subdirectori de dates, escriviu:\n%p2/refetes/%d1/%f +PREFERENCES_OUTDIRTEMPLATEHINT;Podeu usar les següents cadenes de format:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nAquestes cadenes de format refereixen als directoris i sub-paths del path del fitxer RAW.\n\nPer exemple, si /home/tom/image/02-09-2006/dsc0012.nef ha estat obert, el significat de les cadenes de format és:\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 voleu desar la imatge actual en el directori on hi ha l'original, escriviu:\n%p1/%f\n\nSi voleu desar la imatge actual en el directori 'refetes' sota el directori on hi ha l'original, escriviu:\n%p1/refetes/%f\n\nSi voleu desar la imatge actual en el directori '/home/tom/refetes' conservant el mateix subdirectori de dates, 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_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_SELECTICCDIRDLG;Directori de perfils ICC... +PREFERENCES_SELECTLANG;Seleccionar idioma +PREFERENCES_SELECTMONITORPROFDLG;Selecc. perfil ICC del monitor... +PREFERENCES_SELECTTHEME;Seleccionar tema +PREFERENCES_SET;FIXA +PREFERENCES_SHOWBASICEXIF;Mostra inform. bàsica Exif +PREFERENCES_SHOWDATETIME;Indica data i hora +PREFERENCES_SHOWONLYRAW;Exposa només fitxers RAW +PREFERENCES_SHTHRESHOLD;Llindar pèrdues en foscos +PREFERENCES_SINGLETABVERTAB;Mode simple treball, vistes verticals +PREFERENCES_SINGLETAB;Mode simple treball +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_STARTUPIMDIR;Directori inicial de les imatges +PREFERENCES_TAB_BROWSER;Gestor de fitxers +PREFERENCES_TAB_COLORMGR;Maneig del color +PREFERENCES_TAB_GENERAL;General +PREFERENCES_TAB_IMPROC;Processament de la imatge +PREFERENCES_TAB_OUTPUT;Opcions de sortida +PREFERENCES_TAB_SOUND;Sons +PREFERENCES_THUMBSIZE;Tamany minifoto +PREFERENCES_TUNNELMETADATA;Copia IPTC/XMP sense canvis al fitxer de sortida (en treball amb altres progs.) +PREFERENCES_USESYSTEMTHEME; Use tema del sistema +PREFERENCES_WORKFLOW;Flux de treball +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_PCUSTOM;Especial +PROFILEPANEL_PFILE;Del fitxer +PROFILEPANEL_PLASTPHOTO;Darrera foto +PROFILEPANEL_PLASTSAVED;Darrera desada +PROFILEPANEL_PROFILE;Perfil +PROFILEPANEL_SAVEDLGLABEL;Desar paràm. de postprocés... +PROFILEPANEL_TOOLTIPCOPY;Copia perfil actual al portapapers +PROFILEPANEL_TOOLTIPLOAD;Carrega perfil d'un fitxer +PROFILEPANEL_TOOLTIPPASTE; Enganxa perfil del portapapers +PROFILEPANEL_TOOLTIPSAVE;Desa l'actual com a perfil +PROGRESSBAR_BADPIXELS;Píxels dolents... +PROGRESSBAR_CACORRECTION;Correcció AC... +PROGRESSBAR_DARKFRAME;Marc fost... +PROGRESSBAR_DECODING;Decodificant fitxer RAW... +PROGRESSBAR_DEMOSAICING;Demosaicant... +PROGRESSBAR_GREENEQUIL;Equilibri verd... +PROGRESSBAR_LINEDENOISE;Línia desoroll... +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_READY;A punt. +PROGRESSBAR_SAVEJPEG;Desant fitxer JPEG... +PROGRESSBAR_SAVEPNG;Desant fitxer PNG... +PROGRESSBAR_SAVETIFF;Desant fitxer TIFF... +PROGRESSDLG_LOADING;Carregant fitxer... +PROGRESSDLG_PROCESSING;Processant imatge... +PROGRESSDLG_PROFILECHANGEDINBROWSER;Perfil canviat al navegador +PROGRESSDLG_SAVING;Desant fitxer... +QINFO_FOCALLENGTH;Distància focal +QINFO_ISO;ISO +QINFO_LENS;Objectiu +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_PNGFILTER;Fitxers 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_TIFFFILTER;Fitxers TIFF +SAVEDLG_TIFFUNCOMPRESSED;TIFF no comprimit +TOOLBAR_TOOLTIP_CROP;Selecció retall (Tecla: C) +TOOLBAR_TOOLTIP_HAND;Eina mà (Tecla: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Selecc. línia recta (Tecla: S) +TOOLBAR_TOOLTIP_WB;Afina balanç de blancs (Tecla: W) +TP_CACORRECTION_BLUE;Blau +TP_CACORRECTION_LABEL;Correcció A. C. (Aberració Cromàtica) +TP_CACORRECTION_RED;Vermell +TP_CHMIXER_BLUE;Blau +TP_CHMIXER_GREEN;Verd +TP_CHMIXER_LABEL;Barrejador de canals +TP_CHMIXER_RED;Vermell +TP_CHROMATABERR_LABEL;Aberració cromàtica +TP_COARSETRAF_DEGREE;graus: +TP_COARSETRAF_TOOLTIP_HFLIP;Inversió horitzontal +TP_COARSETRAF_TOOLTIP_ROTLEFT;Rotació esquerra +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotació dreta +TP_COARSETRAF_TOOLTIP_VFLIP;Inversió vertical +TP_COLORBOOST_ACHANNEL;Canal "a" +TP_COLORBOOST_AMOUNT;Quantitat +TP_COLORBOOST_AVOIDCOLORCLIP;Evitar pèrdua per color +TP_COLORBOOST_BCHANNEL;Canal "b" +TP_COLORBOOST_CHANNEL;Canal +TP_COLORBOOST_CHSEPARATE;independent +TP_COLORBOOST_ENABLESATLIMITER;Activa limitador de saturació +TP_COLORBOOST_LABEL;Augment de color +TP_COLORBOOST_SATLIMIT;Saturació límit +TP_COLORDENOISE_EDGESENSITIVE;Sensibilitat vores +TP_COLORDENOISE_EDGETOLERANCE;Tolerància vores +TP_COLORDENOISE_LABEL;Reducció del soroll de color +TP_COLORDENOISE_RADIUS;Radi +TP_COLORSHIFT_BLUEYELLOW;Blau-Groc +TP_COLORSHIFT_GREENMAGENTA;Verd-Magenta +TP_COLORSHIFT_LABEL;Canvi de color +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;Fixa proporció: +TP_CROP_GTDIAGONALS;Regla de diagonals +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;A +TP_CROP_LABEL;Retall +TP_CROP_PPI;PPI= +TP_CROP_SELECTCROP; Selecc. retall +TP_CROP_W;L +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_DETAIL_AMOUNT;Quantitat +TP_DIRPYRDENOISE_CHROMA;Crominància +TP_DIRPYRDENOISE_GAMMA;Gama +TP_DIRPYRDENOISE_LABEL;Reducció de soroll +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_EQUALIZER_CONTRAST_MINUS;Contrast- +TP_EQUALIZER_CONTRAST_PLUS;Contrast+ +TP_EQUALIZER_FINEST;més fi +TP_EQUALIZER_LABEL;Equalitzador d'ónula +TP_EQUALIZER_LARGEST;més bast +TP_EQUALIZER_NEUTRAL;Neutral +TP_EXPOSCORR_LABEL;Punt blanc raw +TP_EXPOSURE_AUTOLEVELS;Nivells automàtics +TP_EXPOSURE_BLACKLEVEL;Negre +TP_EXPOSURE_BRIGHTNESS;Brillantor +TP_EXPOSURE_CLIP;Retall +TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Llindar recup. clars intensos +TP_EXPOSURE_COMPRHIGHLIGHTS;Compressió de clars +TP_EXPOSURE_COMPRSHADOWS;Compressió de foscos +TP_EXPOSURE_CONTRAST;Contrast +TP_EXPOSURE_CURVEEDITOR;Corba de to +TP_EXPOSURE_EXPCOMP;Compens. d'exposició +TP_EXPOSURE_LABEL;Exposició +TP_EXPOSURE_SATURATION;Saturació +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_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_HSVEQUALIZER1;Vermell +TP_HSVEQUALIZER2;Groc +TP_HSVEQUALIZER3;Llima +TP_HSVEQUALIZER4;Verd +TP_HSVEQUALIZER5;Aquós +TP_HSVEQUALIZER6;Blau +TP_HSVEQUALIZER7;Porpra +TP_HSVEQUALIZER8;Magenta +TP_HSVEQUALIZER_CHANNEL;Canal HSV +TP_HSVEQUALIZER_HUE;H +TP_HSVEQUALIZER_LABEL;HSV Equalitzador +TP_HSVEQUALIZER_NEUTRAL;Neutral +TP_HSVEQUALIZER_SAT;S +TP_HSVEQUALIZER_VAL;V +TP_ICM_FILEDLGFILTERANY;Tots els fitxers +TP_ICM_FILEDLGFILTERICM;Fitxers de perfils ICC +TP_ICM_GAMMABEFOREINPUT;El perfil aplica Gamma +TP_ICM_INPUTCAMERA;Propi de la càmera +TP_ICM_INPUTCUSTOM;Especial +TP_ICM_INPUTDLGLABEL;Selecc. perfil d'entrada ICC... +TP_ICM_INPUTEMBEDDED;Usar l'encastat si és possible +TP_ICM_INPUTNONE;Sense perfil +TP_ICM_INPUTPROFILE;Perfil d'entrada +TP_ICM_LABEL;ICM +TP_ICM_NOICM;No cap ICM: Sortida sRGB +TP_ICM_OUTPUTDLGLABEL;Selecc. perfil de sortida ICC... +TP_ICM_OUTPUTPROFILE;Perfil de sortida +TP_ICM_SAVEREFERENCE;Desa com a imatge de ref. als perfils +TP_ICM_WORKINGPROFILE;Perfil de treball +TP_IMPULSEDENOISE_LABEL;Impuls Reducció de Soroll +TP_IMPULSEDENOISE_THRESH;Llindar d'impuls RS +TP_LABCURVE_AVOIDCOLORCLIP;Evita estralls de color +TP_LABCURVE_BRIGHTNESS;Brillantor +TP_LABCURVE_CONTRAST;Contrast +TP_LABCURVE_CURVEEDITOR;Corba de luminància +TP_LABCURVE_ENABLESATLIMITER;Aplica limitador de saturació +TP_LABCURVE_LABEL;Ajustos Lab +TP_LABCURVE_SATLIMIT;Saturació límit +TP_LABCURVE_SATURATION;Saturació +TP_LENSGEOM_AUTOCROP;Auto cropa +TP_LENSGEOM_FILL;Auto omple +TP_LENSGEOM_LABEL;Lent / Geometria +TP_LUMACURVE_BLACKLEVEL;Negre +TP_LUMACURVE_BRIGHTNESS;Brillantor +TP_LUMACURVE_COMPRHIGHLIGHTS;Compressió de clars +TP_LUMACURVE_COMPRSHADOWS;Compressió de foscos +TP_LUMACURVE_CONTRAST;Contrast +TP_LUMACURVE_CURVEEDITOR;Corba de luminància +TP_LUMACURVE_LABEL;Corba de luminància +TP_LUMADENOISE_EDGETOLERANCE;Tolerància vores +TP_LUMADENOISE_LABEL;Reducció de soroll de luminància +TP_LUMADENOISE_RADIUS;Radi +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_LINEAR;Factor de correcció linear +TP_RAWEXPOS_PRESER;Correc. clars intensos preservant (EV) +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_DOWNSCALEB;Empetitir (millor) +TP_RESIZE_DOWNSCALEF;Empetitir (ràpid) +TP_RESIZE_FITBOX;Capsa d'inclusió +TP_RESIZE_FULLIMAGE;Imatge sencera +TP_RESIZE_FULLSIZE;Tamany 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_ROTATE_AUTOCROP;Auto retalla +TP_ROTATE_DEGREE;Graus +TP_ROTATE_FILL;Omple +TP_ROTATE_LABEL;Rota +TP_ROTATE_SELECTLINE; Selecc. línia recta +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Clars intensos +TP_SHADOWSHLIGHTS_HLTONALW;Amplada de to +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 +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_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_CUSTOM;Especial +TP_WBALANCE_GREEN;Tint +TP_WBALANCE_LABEL;Balanç de blancs +TP_WBALANCE_METHOD;Mètode +TP_WBALANCE_SIZE;Tamany: +TP_WBALANCE_SPOTWB;Punt b. blancs +TP_WBALANCE_TEMPERATURE;Temperatura +ZOOMBAR_DETAIL;Detall +ZOOMBAR_HUGE;Enorme +ZOOMBAR_LARGE;Gran +ZOOMBAR_NORMAL;Normal +ZOOMBAR_PREVIEW;Previsualització +ZOOMBAR_SCALE;Escala +ZOOMBAR_SMALL;Petit +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;Obre una altra finestra de detall +ZOOMPANEL_ZOOM100;Zoom 100% 1 +ZOOMPANEL_ZOOMFITSCREEN;Ajusta a la finestra F +ZOOMPANEL_ZOOMIN;Apropa + +ZOOMPANEL_ZOOMOUT;Allunya - + +#00 Catala +#01 10.10.2009: JMG +# Cropar: Seleccionar una àrea per a treballar i excloure tota la resta +# Defringe: desserrellar + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!ABOUT_TAB_RELEASENOTES;Release Notes +!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_SHARPENEDGE;Bypass Edge Sharpening +!EXPORT_BYPASS_SHARPENING;Bypass Sharpening +!EXPORT_BYPASS_SHARPENMICRO;Bypass Microcontrast +!EXPORT_BYPASS_SH_HQ;Bypass Shadow/Highlights (High Quality) +!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_EXEC_CPB;Custom Profile Builder +!FILEBROWSER_EXTPROGMENU;Open with +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!FILEBROWSER_POPUPCOLORLABEL0;Label: None +!FILEBROWSER_POPUPCOLORLABEL1;Label: Red +!FILEBROWSER_POPUPCOLORLABEL2;Label: Yellow +!FILEBROWSER_POPUPCOLORLABEL3;Label: Green +!FILEBROWSER_POPUPCOLORLABEL4;Label: Blue +!FILEBROWSER_POPUPCOLORLABEL5;Label: Purple +!FILEBROWSER_POPUPCOLORLABEL;Color label +!FILEBROWSER_POPUPFILEOPERATIONS;File Operations +!FILEBROWSER_POPUPPROCESSFAST;Put to Queue (Fast export) +!FILEBROWSER_POPUPPROFILEOPERATIONS;Processing Profile Operations +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!FILEBROWSER_QUERYHINT;Type a partial filename to search for.\nCtrl-F to focus the Find text box (in the File Browser).\nEnter to commence search. +!FILEBROWSER_QUERYLABEL; Find: +!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-` +!GENERAL_WARNING;Warning +!HISTOGRAM_BUTTON_BAR;RGB +!HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar\nClick right mouse button on image preview to freeze/unfreeze +!HISTOGRAM_TOOLTIP_FULL;Toggle full or scaled histogram +!HISTORY_MSG_130;Auto Distorion +!HISTORY_MSG_131;Noise Reduction Luma +!HISTORY_MSG_132;Noise Reduction Chroma +!HISTORY_MSG_133;Gamma +!HISTORY_MSG_134;Gamma Position +!HISTORY_MSG_135;Gamma Free +!HISTORY_MSG_136;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 Green Together +!HISTORY_MSG_142;Edges Sharpening - Iterations +!HISTORY_MSG_143;Edges Sharpening - Quantity +!HISTORY_MSG_144;Microcontrast - Quantity +!HISTORY_MSG_145;Microcontrast - Uniformity +!HISTORY_MSG_146;Edges Sharpening +!HISTORY_MSG_147;Edges Sharpening - 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;Vibrance - Pastel tones +!HISTORY_MSG_153;Vibrance - Saturated tones +!HISTORY_MSG_154;Vibrance - Protect skin tones +!HISTORY_MSG_155;Vibrance - Avoid color drift +!HISTORY_MSG_156;Vibrance - Link pastel and saturated tones +!HISTORY_MSG_157;Vibrance - Pastel/Saturated threshold +!HISTORY_MSG_158;Strength +!HISTORY_MSG_159;Edge Stopping +!HISTORY_MSG_160;Scale +!HISTORY_MSG_161;Reweighting Iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_163;RGB Curves - R +!HISTORY_MSG_164;RGB Curves - G +!HISTORY_MSG_165;RGB Curves - B +!HISTORY_MSG_166;Neutral Levels +!HISTORY_MSG_167;B&W Toning +!HISTORY_MSG_168;'Cc' curve +!HISTORY_MSG_169;'Ch' curve +!HISTORY_MSG_170;Vibrance - Curve +!MAIN_MSG_EMPTYFILENAME;Filename unspecified! +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue processed first. +!MAIN_TAB_EXPORT; Export +!MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 8 +!MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 0 +!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_EPD;Tone Mapping +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_RAWEXPOS_BLACK;Black Level +!PARTIALPASTE_RAW_ALLENHANCE;Apply post demosaic artifact/noise reduction +!PARTIALPASTE_RGBCURVES;RGB curves +!PARTIALPASTE_SHARPENEDGE;Edges +!PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_VIBRANCE;Vibrance +!PREFERENCES_CUSTPROFBUILDHINT;Executable (or script) file called when a new initial processing profile should be generated for an image.\nReceives command line parameters to allow a rules-based processing profile generation:\n[raw/JPG path] [default processing profile path] [f-number] [exposure in secs] [focal length in mm] [ISO] [lens] [camera] +!PREFERENCES_CUSTPROFBUILDPATH;Executable path +!PREFERENCES_CUSTPROFBUILD;Custom Processing Profile Builder +!PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar (de-select for low res display) +!PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogram in left panel +!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_PANFACTORFRAME;Pan Rate Amplification +!PREFERENCES_PANFACTORLABEL;Factor +!PREFERENCES_SHOWEXPOSURECOMPENSATION;Append exposure compensation +!PREFERENCES_SHOWPROFILESELECTOR;Show processing profile selector +!PREFERENCES_SLIMUI;Slim interface +!PREFERENCES_SND_TRESHOLDSECS;after secs +!PREFERENCES_SQUAREDETAILWINDOW;Square detail window (faster) +!PREFERENCES_TP_LABEL;Tool panel: +!PREFERENCES_TP_USEICONORTEXT;Use tab icons instead of text +!PREFERENCES_TP_VSCROLLBAR;Hide vertical scrollbar +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_SAVEPPASTE;Parameters to save +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing Profile Saved +!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\nthe 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_CROP_GTEPASSPORT;Biometric Passport +!TP_CROP_GTFRAME;Frame +!TP_CROP_GTGRID;Grid +!TP_EPD_EDGESTOPPING;Edge stopping +!TP_EPD_LABEL;Tone Mapping +!TP_EPD_REWEIGHTINGITERATES;Reweighting iterates +!TP_EPD_SCALE;Scale +!TP_EPD_STRENGTH;Strength +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggle execution of Auto Levels to automatically set parameter values based on image analysis +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in auto levels operation +!TP_EXPO_AFTER; After interpolation (before RGB conversion) +!TP_HLREC_BLEND;Blend +!TP_ICM_BLENDCMSMATRIX;Blend highlights with matrix +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover blown highlights when using LUT based ICC profiles +!TP_ICM_INPUTCAMERAICC;Auto-matched camera-specific color profile +!TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profile. These profiles are more precise than simpler matrix ones. Available for some 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_PREFERREDPROFILE;Preferred DCP profile +!TP_ICM_PREFERREDPROFILE_1;Daylight +!TP_ICM_PREFERREDPROFILE_2;Tungsten +!TP_ICM_PREFERREDPROFILE_3;Fluorescent +!TP_ICM_PREFERREDPROFILE_4;Flash +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid Color Shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space\nand apply Munsell correction +!TP_LABCURVE_BWTONING;B&W Toning +!TP_LABCURVE_BWTONING_TIP;With B&W Toning option enabled, the Lab Chromaticity, Cc and Ch curves are not in effect.\nToning can be achieved using the a and b curves +!TP_LABCURVE_CHROMATICITY;Chromaticity +!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 the Chromaticity +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to the Hue +!TP_LABCURVE_RSTPROTECTION;Red and Skin Tones Protection +!TP_LENSPROFILE_FILEDLGFILTERLCP;Lens correction files +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;Use CA correction +!TP_LENSPROFILE_USEDIST;Use distortion correction +!TP_LENSPROFILE_USEVIGN;Use vignette correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset exposure controls to neutral values +!TP_PREPROCESS_HOTDEADPIXTHRESH;Hot/dead pixel detection threshold +!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 (leader) +!TP_RAWEXPOS_TWOGREEN;Two greens together +!TP_RAW_ALLENHANCE;Apply post demosaic artifact/noise reduction +!TP_RGBCURVES_BLUE;B +!TP_RGBCURVES_CHANNEL;Channel +!TP_RGBCURVES_GREEN;G +!TP_RGBCURVES_LABEL;RGB Curves +!TP_RGBCURVES_RED;R +!TP_SHARPENEDGE_AMOUNT;Quantity +!TP_SHARPENEDGE_LABEL;Edges +!TP_SHARPENEDGE_PASSES;Iterations +!TP_SHARPENEDGE_THREE;Luminance only +!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 the Hue +!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_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 diff --git a/rtdata/languages/Chinese (Simplified) b/rtdata/languages/Chinese (Simplified) new file mode 100644 index 000000000..6e840ef17 --- /dev/null +++ b/rtdata/languages/Chinese (Simplified) @@ -0,0 +1,1213 @@ +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_DIALOGLABEL;按Exif筛选 +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_ARRANGEMENTHINT;切换缩略图对齐方式 +FILEBROWSER_CLEARPROFILE;清空配置 +FILEBROWSER_COPYPROFILE;复制配置 +FILEBROWSER_DELETEDLGLABEL;确认删除 +FILEBROWSER_DELETEDLGMSG;确定删除所选的%1个文件? +FILEBROWSER_EMPTYTRASHHINT;永久清空垃圾箱 +FILEBROWSER_EMPTYTRASH;清空垃圾箱 +FILEBROWSER_EXIFFILTERAPPLYHINT;文件浏览器Exif筛选开关 +FILEBROWSER_EXIFFILTERAPPLY;应用 +FILEBROWSER_EXIFFILTERLABEL;Exif筛选 +FILEBROWSER_EXIFFILTERSETTINGSHINT;更改Exif筛选设置 +FILEBROWSER_EXIFFILTERSETTINGS;设置 +FILEBROWSER_PARTIALPASTEPROFILE;选择性粘贴 +FILEBROWSER_PASTEPROFILE;粘贴配置 +FILEBROWSER_POPUPCANCELJOB;取消任务 +FILEBROWSER_POPUPMOVEEND;移动到队列尾部 +FILEBROWSER_POPUPMOVEHEAD;移动到队列头部 +FILEBROWSER_POPUPOPEN;打开 +FILEBROWSER_POPUPPROCESS;放入队列 +FILEBROWSER_POPUPRANK1;评 1 星 +FILEBROWSER_POPUPRANK2;评 2 星 +FILEBROWSER_POPUPRANK3;评 3 星 +FILEBROWSER_POPUPRANK4;评 4 星 +FILEBROWSER_POPUPRANK5;评 5 星 +FILEBROWSER_POPUPREMOVE;从文件系统中移除 +FILEBROWSER_POPUPRENAME;重命名 +FILEBROWSER_POPUPSELECTALL;全部选中 +FILEBROWSER_POPUPTRASH;移动到垃圾箱 +FILEBROWSER_POPUPUNRANK;取消星级 +FILEBROWSER_POPUPUNTRASH;从垃圾箱中移除 +FILEBROWSER_PROCESSINGSETTINGSHINT;设置文件格式及输出文件夹 +FILEBROWSER_PROCESSINGSETTINGS;设置 +FILEBROWSER_RENAMEDLGLABEL;文件重命名 +FILEBROWSER_RENAMEDLGMSG;将"%1"更名为: +FILEBROWSER_SHOWDIRHINT;显示文件夹中所有图片 +FILEBROWSER_SHOWQUEUEHINT;显示队列内容 +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_LOAD;读取 +GENERAL_NA;不适用 +GENERAL_NO;否 +GENERAL_OK;确定 +GENERAL_PORTRAIT;纵向 +GENERAL_SAVE;保存 +GENERAL_YES;是 +HISTOGRAM_LABEL;直方图 +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_NEWSNAPSHOTAS;为... +HISTORY_NEWSNAPSHOT;新建快照 +HISTORY_NEWSSDIALOGLABEL;快照标签: +HISTORY_NEWSSDIALOGTITLE;添加新快照 +HISTORY_SETTO;设置为 +HISTORY_SNAPSHOTS;系列快照 +HISTORY_SNAPSHOT;快照 +ICMPANEL_FILEDLGFILTERANY;任意文件 +ICMPANEL_FILEDLGFILTERICM;ICC配置文件 +ICMPANEL_GAMMABEFOREINPUT;配置使用Gamma校正 +ICMPANEL_INPUTCAMERA;相机缺省 +ICMPANEL_INPUTCUSTOM;自定义 +ICMPANEL_INPUTDLGLABEL;选择输入ICC配置... +ICMPANEL_INPUTEMBEDDED;如可能,使用内置 +ICMPANEL_INPUTPROFILE;输入配置 +ICMPANEL_NOICM;No ICM: sRGB配置 +ICMPANEL_OUTPUTDLGLABEL;选择输出ICC配置... +ICMPANEL_OUTPUTPROFILE;输出配置 +ICMPANEL_SAVEREFERENCE;保存参考图片用于生成配置信息 +ICMPANEL_WORKINGPROFILE;当前配置 +IMAGEAREA_DETAILVIEW;细节视图 +IPTCPANEL_AUTHORHINT;作者姓名 +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_EXIT;退出 +MAIN_BUTTON_PREFERENCES;参数设置 +MAIN_BUTTON_QUEUE;放入序列 +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_EXITJOBSINQUEUEINFO;退出时队列中未处理的图片将被丢弃。 +MAIN_MSG_EXITJOBSINQUEUEQUEST;队列中尚有图片未处理,确认退出? +MAIN_MSG_JOBSINQUEUE;任务列队中 +MAIN_MSG_QOVERWRITE;是否覆盖? +MAIN_TAB_BASIC;基本 +MAIN_TAB_COLOR;色彩 +MAIN_TAB_DETAIL;详细 +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;曝光 +MAIN_TAB_FILTER;Filter +MAIN_TAB_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;元数据 +MAIN_TAB_TAGGING;标签 +MAIN_TAB_TRANSFORM;转换 +MAIN_TOOLTIP_HIDEFP;显示/隐藏底部面板 (目录和文件浏览器,快捷键: F) +MAIN_TOOLTIP_HIDEHP;显示/隐藏左面板 (包含历史, 快捷键: H) +MAIN_TOOLTIP_INDCLIPPEDH;高光溢出提示 +MAIN_TOOLTIP_INDCLIPPEDS;阴影不足提示 +MAIN_TOOLTIP_PREFERENCES;设置参数 +MAIN_TOOLTIP_QINFO;图片快捷信息 +MAIN_TOOLTIP_SAVEAS;图片存于指定文件夹 +MAIN_TOOLTIP_SAVE;图片存于缺省文件夹 +PARTIALPASTE_BASICGROUP;基本设置 +PARTIALPASTE_CACORRECTION;色彩校正 +PARTIALPASTE_COARSETRANS;90度旋转/翻转 +PARTIALPASTE_COLORBOOST;色彩增强 +PARTIALPASTE_COLORDENOISE;色彩降噪 +PARTIALPASTE_COLORGROUP;色彩相关设定 +PARTIALPASTE_COLORMIXER;色彩混合器 +PARTIALPASTE_COLORSHIFT;色彩偏移 +PARTIALPASTE_COMPOSITIONGROUP;构图设置 +PARTIALPASTE_CROP;剪裁 +PARTIALPASTE_DIALOGLABEL;选择性粘贴配置 +PARTIALPASTE_DISTORTION;形变校正 +PARTIALPASTE_EXIFCHANGES;对exif所做的修改 +PARTIALPASTE_EXPOSURE;曝光 +PARTIALPASTE_HLRECOVERY;高感光修复 +PARTIALPASTE_ICMSETTINGS;ICM 设置 +PARTIALPASTE_IPTCINFO;IPTC 信息 +PARTIALPASTE_LENSGROUP;镜头相关设置 +PARTIALPASTE_LUMACURVE;亮度曲线 +PARTIALPASTE_LUMADENOISE;亮度降噪 +PARTIALPASTE_LUMINANCEGROUP;亮度相关设置 +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_CACHESTRAT1;较高速度 +PREFERENCES_CACHESTRAT2;较低内存占用率 +PREFERENCES_CACHESTRAT;缓存方案 +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_DEMOSAICINGALGO;马赛克还原算法 +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_HINT;提示 +PREFERENCES_HLTHRESHOLD;高光溢出阈值 +PREFERENCES_ICCDIR;ICC配置路径 +PREFERENCES_IMPROCPARAMS;缺省图片处理参数 +PREFERENCES_INTENT_ABSOLUTE;绝对色彩模式 +PREFERENCES_INTENT_PERCEPTUAL;感知模式 +PREFERENCES_INTENT_RELATIVE;相对色彩模式 +PREFERENCES_INTENT_SATURATION;饱和度 +PREFERENCES_LIVETHUMBNAILS;实时缩略图(较慢) +PREFERENCES_MONITORICC;显示器配置 +PREFERENCES_OUTDIRFOLDERHINT;将已寸图片放至所选文件夹 +PREFERENCES_OUTDIRFOLDER;保存至文件夹 +PREFERENCES_OUTDIRHINT;可以使用下列控制符:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\n这些控制符指向RAW文件所在文件夹及子文件夹。\n\n例如 假如 /home/tom/image/02-09-2006/dsc0012.nef已经打开,控制符的意义如下:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\n如果想将输出文件保存到输入文件所在位置:\n%p1/%f\n\n如果想将输出文件保存至输入文件夹内的'converted'子文件夹:\n%p1/converted/%f\n\n如果想将输出文件保存至 '/home/tom/converted' 并保留按日期所分的子文件夹:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATEHINT;可以使用下列控制符:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\n这些控制符指向RAW文件所在文件夹及子文件夹。\n\n例如 假如 /home/tom/image/02-09-2006/dsc0012.nef已经打开,控制符的意义如下:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\n如果想将输出文件保存到输入文件所在位置:\n%p1/%f\n\n如果想将输出文件保存至输入文件夹内的'converted'子文件夹:\n%p1/converted/%f\n\n如果想将输出文件保存至 '/home/tom/converted' 并保留按日期所分的子文件夹:\n%p2/converted/%d1/%f +PREFERENCES_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_SELECTICCDIRDLG;选择ICC路径... +PREFERENCES_SELECTLANG;选择语言 +PREFERENCES_SELECTMONITORPROFDLG;选择显示器ICC路径... +PREFERENCES_SELECTTHEME;选择主题 +PREFERENCES_SHOWBASICEXIF;显示基本Exif信息 +PREFERENCES_SHOWDATETIME;显示时间日期 +PREFERENCES_SHOWONLYRAW;仅显示Raw文件 +PREFERENCES_SHTHRESHOLD;阴影过暗阈值 +PREFERENCES_STARTUPIMDIR;启动时路径 +PREFERENCES_TAB_BROWSER;文件浏览器 +PREFERENCES_TAB_COLORMGR;色彩管理 +PREFERENCES_TAB_GENERAL;一般 +PREFERENCES_TAB_IMPROC;图片处理 +PREFERENCES_TAB_OUTPUT;输出选项 +PREFERENCES_THUMBSIZE;缩略图大小 +PROFILEPANEL_FILEDLGFILTERANY;任意文件 +PROFILEPANEL_FILEDLGFILTERPP;处理参数配置 +PROFILEPANEL_LABEL;处理参数配置 +PROFILEPANEL_LOADDLGLABEL;加载处理参数为... +PROFILEPANEL_PCUSTOM;自定义 +PROFILEPANEL_PFILE;由文件 +PROFILEPANEL_PLASTPHOTO;上次图片 +PROFILEPANEL_PLASTSAVED;上次保存 +PROFILEPANEL_PROFILE;配置 +PROFILEPANEL_SAVEDLGLABEL;保存处理参数为... +PROFILEPANEL_TOOLTIPCOPY;将当前配置复制到剪贴板 +PROFILEPANEL_TOOLTIPLOAD;由文件加载配置 +PROFILEPANEL_TOOLTIPPASTE;从剪贴板粘贴配置 +PROFILEPANEL_TOOLTIPSAVE;保存当前配置 +PROGRESSBAR_DECODING;Raw文件解码中... +PROGRESSBAR_DEMOSAICING;马赛克还原中... +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_FOCALLENGTH;焦距 +QINFO_ISO;感光度 +QINFO_LENS;Lens +QINFO_NOEXIF;Exif数据不可用. +SAVEDLG_FILEFORMAT;文件格式 +SAVEDLG_JPEGQUAL;JPEG质量 +SAVEDLG_JPGFILTER;JPEG文件 +SAVEDLG_PNGCOMPR;PNG压缩 +SAVEDLG_PNGFILTER;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_OUTPUTDLGLABEL;选择输出ICC配置... +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_LUMADENOISE_EDGETOLERANCE;边缘容差 +TP_LUMADENOISE_LABEL;亮度噪点抑制 +TP_LUMADENOISE_RADIUS;半径 +TP_RESIZE_BICUBICSF;双三次 (柔化) +TP_RESIZE_BICUBICSH;双三次 (锐化) +TP_RESIZE_BICUBIC;双三次 +TP_RESIZE_BILINEAR;双线性 +TP_RESIZE_FULLSIZE;全照片尺寸: +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;色温 +ZOOMBAR_DETAIL;细节 +ZOOMBAR_HUGE;很大 +ZOOMBAR_LARGE;大 +ZOOMBAR_NORMAL;普通 +ZOOMBAR_PREVIEW;预览 +ZOOMBAR_SCALE;比例 +ZOOMBAR_SMALL;小 + +#00 Chinese (Simplified) +#01 06.11.2008 +#02 Chinese simplified +#03 Yang Gao (grantyale) +#04 Added new translations for 2.4beta, fixed mistranslations(eg. Vignetting - 暗角/失光 instead of 紫边 which corresponds to purple fringing, and RL Deconvolution) +#05 based on Version 13.2.2008 by Forrest Sun + +!!!!!!!!!!!!!!!!!!!!!!!!! +! 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 +!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_SHARPENEDGE;Bypass Edge Sharpening +!EXPORT_BYPASS_SHARPENING;Bypass Sharpening +!EXPORT_BYPASS_SHARPENMICRO;Bypass Microcontrast +!EXPORT_BYPASS_SH_HQ;Bypass Shadow/Highlights (High Quality) +!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 the path text box.\nEnter / Ctrl-Enter (in the File Browser) to browse there;\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_CURRENT_NAME;Current name: +!FILEBROWSER_DARKFRAME;Dark frame +!FILEBROWSER_DELETEDLGMSGINCLPROC;Are you sure you want to delete the selected %1 files including a queue-processed version? +!FILEBROWSER_EXEC_CPB;Custom Profile Builder +!FILEBROWSER_EXTPROGMENU;Open with +!FILEBROWSER_FLATFIELD;Flat Field +!FILEBROWSER_MOVETODARKFDIR;Move to dark frames directory +!FILEBROWSER_MOVETOFLATFIELDDIR;Move to flat fields directory +!FILEBROWSER_NEW_NAME;New name: +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!FILEBROWSER_POPUPCOLORLABEL0;Label: None +!FILEBROWSER_POPUPCOLORLABEL1;Label: Red +!FILEBROWSER_POPUPCOLORLABEL2;Label: Yellow +!FILEBROWSER_POPUPCOLORLABEL3;Label: Green +!FILEBROWSER_POPUPCOLORLABEL4;Label: Blue +!FILEBROWSER_POPUPCOLORLABEL5;Label: Purple +!FILEBROWSER_POPUPCOLORLABEL;Color label +!FILEBROWSER_POPUPCOPYTO;Copy to... +!FILEBROWSER_POPUPFILEOPERATIONS;File Operations +!FILEBROWSER_POPUPMOVETO;Move to... +!FILEBROWSER_POPUPPROCESSFAST;Put to Queue (Fast export) +!FILEBROWSER_POPUPPROFILEOPERATIONS;Processing Profile Operations +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_POPUPREMOVESUBMENU;Remove +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!FILEBROWSER_QUERYHINT;Type a partial filename to search for.\nCtrl-F to focus the Find text box (in the File Browser).\nEnter to commence search. +!FILEBROWSER_QUERYLABEL; Find: +!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 +!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-` +!FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +!FILEBROWSER_USETEMPLATE;Use template: +!GENERAL_AFTER;After +!GENERAL_BEFORE;Before +!GENERAL_FILE;File +!GENERAL_HIGH_QUALITY;High Quality +!GENERAL_NONE;None +!GENERAL_UNCHANGED;(Unchanged) +!GENERAL_WARNING;Warning +!HISTOGRAM_BUTTON_BAR;RGB +!HISTOGRAM_BUTTON_B;B +!HISTOGRAM_BUTTON_G;G +!HISTOGRAM_BUTTON_L;L +!HISTOGRAM_BUTTON_RAW;Raw +!HISTOGRAM_BUTTON_R;R +!HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar\nClick right mouse button on image preview to freeze/unfreeze +!HISTOGRAM_TOOLTIP_FULL;Toggle full or scaled histogram +!HISTOGRAM_TOOLTIP_RAW;Show/Hide raw histogram +!HISTORY_MSG_82;Profile Changed +!HISTORY_MSG_83;High Quality Shadows/Highlights +!HISTORY_MSG_84;Perspective Correction +!HISTORY_MSG_85;Lens Correction Profile +!HISTORY_MSG_86;Wavelet Equalizer +!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 +!HISTORY_MSG_92;NR - Gamma +!HISTORY_MSG_93;Contrast by Detail Levels Value +!HISTORY_MSG_94;Contrast by Detail Levels +!HISTORY_MSG_95;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;RGB Saturation +!HISTORY_MSG_101;HSV EQ -- Hue +!HISTORY_MSG_102;HSV EQ -- Saturation +!HISTORY_MSG_103;HSV EQ -- Value +!HISTORY_MSG_104;HSV Equalizer +!HISTORY_MSG_105;Defringing +!HISTORY_MSG_106;Defringing Radius +!HISTORY_MSG_107;Defringing Threshold +!HISTORY_MSG_108;Highlight Compr. Threshold +!HISTORY_MSG_109;Resize Bounding Box +!HISTORY_MSG_110;Resizing applies o +!HISTORY_MSG_111;Avoid Color Shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;Red and Skin Tones Protection +!HISTORY_MSG_114;DCB Iterations +!HISTORY_MSG_115;False Color Iterations +!HISTORY_MSG_116;Enhanced DCB +!HISTORY_MSG_117;Red CA Correction +!HISTORY_MSG_118;Blue CA Correction +!HISTORY_MSG_119;Line Denoise +!HISTORY_MSG_120;Green Equil. Threshold +!HISTORY_MSG_121;Auto CA +!HISTORY_MSG_122;Auto Dark Frame +!HISTORY_MSG_123;Dark Frame File +!HISTORY_MSG_124;Linear Exp. Correction +!HISTORY_MSG_125;Exp. Correction Preserving HL +!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;Gamma +!HISTORY_MSG_134;Gamma Position +!HISTORY_MSG_135;Gamma Free +!HISTORY_MSG_136;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 Green Together +!HISTORY_MSG_142;Edges Sharpening - Iterations +!HISTORY_MSG_143;Edges Sharpening - Quantity +!HISTORY_MSG_144;Microcontrast - Quantity +!HISTORY_MSG_145;Microcontrast - Uniformity +!HISTORY_MSG_146;Edges Sharpening +!HISTORY_MSG_147;Edges Sharpening - 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;Vibrance - Pastel tones +!HISTORY_MSG_153;Vibrance - Saturated tones +!HISTORY_MSG_154;Vibrance - Protect skin tones +!HISTORY_MSG_155;Vibrance - Avoid color drift +!HISTORY_MSG_156;Vibrance - Link pastel and saturated tones +!HISTORY_MSG_157;Vibrance - Pastel/Saturated threshold +!HISTORY_MSG_158;Strength +!HISTORY_MSG_159;Edge Stopping +!HISTORY_MSG_160;Scale +!HISTORY_MSG_161;Reweighting Iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_163;RGB Curves - R +!HISTORY_MSG_164;RGB Curves - G +!HISTORY_MSG_165;RGB Curves - B +!HISTORY_MSG_166;Neutral Levels +!HISTORY_MSG_167;B&W Toning +!HISTORY_MSG_168;'Cc' curve +!HISTORY_MSG_169;'Ch' curve +!HISTORY_MSG_170;Vibrance - Curve +!MAIN_BUTTON_FULLSCREEN;Fullscreen +!MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Put current image to processing queue.\nShortcut: Ctrl+Q +!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_ERRORDURINGIMAGESAVING;Error during image saving +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue processed first. +!MAIN_MSG_NAVIGATOR;Navigator +!MAIN_MSG_PLACES;Places +!MAIN_TAB_COLOR_TOOLTIP;Shortcut: Alt-C +!MAIN_TAB_DETAIL_TOOLTIP;Shortcut: Alt-D +!MAIN_TAB_EXPORT; 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_TOGGLE_BEFORE_AFTER;B|A +!MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 8 +!MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 0 +!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_CHANNELMIXER;Channel mixer +!PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto fill +!PARTIALPASTE_DARKFRAMEAUTOSELECT;Dark Frame Auto Select +!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;FF Auto Select +!PARTIALPASTE_FLATFIELDBLURRADIUS;FF Blur Radius +!PARTIALPASTE_FLATFIELDBLURTYPE;FF Blur Type +!PARTIALPASTE_FLATFIELDFILE;Flat field (FF) File +!PARTIALPASTE_HLRECONSTRUCTION;Highlight reconstruction +!PARTIALPASTE_HLRECOVERYAMOUNT;Highlight recovery amount +!PARTIALPASTE_HLRECOVERYTHRESHOLD;Highlight recovery threshold +!PARTIALPASTE_HSVEQUALIZER;HSV Equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!PARTIALPASTE_LABCURVE;Lab adjustments +!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 Level +!PARTIALPASTE_RAWEXPOS_LINEAR;Raw white point linear corr. factor +!PARTIALPASTE_RAWEXPOS_PRESER;Raw white point HL preserving corr. (EV) +!PARTIALPASTE_RAWGROUP;Raw settings +!PARTIALPASTE_RAW_ALLENHANCE;Apply post demosaic artifact/noise reduction +!PARTIALPASTE_RAW_DCBENHANCE;Apply DCB enhancement step +!PARTIALPASTE_RAW_DCBITERATIONS;Number of DCB iterations +!PARTIALPASTE_RAW_DMETHOD;Demosaic Method +!PARTIALPASTE_RAW_FALSECOLOR;Demosaic False color suppression steps +!PARTIALPASTE_RGBCURVES;RGB curves +!PARTIALPASTE_SHARPENEDGE;Edges +!PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_VIBRANCE;Vibrance +!PARTIALPASTE_WAVELETEQUALIZER;Wavelet equalizer +!PREFERENCES_ADD;ADD +!PREFERENCES_AUTOMONPROFILE;Automatically use operating system's main monitor color profile +!PREFERENCES_BATCH_PROCESSING;Batch Processing +!PREFERENCES_BEHAVIOR;Behavior +!PREFERENCES_CUSTPROFBUILDHINT;Executable (or script) file called when a new initial processing profile should be generated for an image.\nReceives command line parameters to allow a rules-based processing profile generation:\n[raw/JPG path] [default processing profile path] [f-number] [exposure in secs] [focal length in mm] [ISO] [lens] [camera] +!PREFERENCES_CUSTPROFBUILDPATH;Executable path +!PREFERENCES_CUSTPROFBUILD;Custom Processing Profile Builder +!PREFERENCES_CUTOVERLAYBRUSH;Crop mask color/transparency +!PREFERENCES_DARKFRAMEFOUND;Found +!PREFERENCES_DARKFRAMESHOTS;shots +!PREFERENCES_DARKFRAMETEMPLATES;templates +!PREFERENCES_DARKFRAME;Dark Frame +!PREFERENCES_DATEFORMATFRAME;Date Format +!PREFERENCES_DIRDARKFRAMES;Dark frames directory +!PREFERENCES_EDITORLAYOUT;Editor Layout +!PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar (de-select for low res display) +!PREFERENCES_FLATFIELDFOUND;Found +!PREFERENCES_FLATFIELDSDIR;Flat Fields directory +!PREFERENCES_FLATFIELDSHOTS;shots +!PREFERENCES_FLATFIELDTEMPLATES;templates +!PREFERENCES_FLATFIELD;Flat Field +!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_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). On Windows use "SystemDefault", "SystemAsterisk" etc. for system sounds. +!PREFERENCES_SND_LNGEDITPROCDONE;Editor processing done +!PREFERENCES_SND_TRESHOLDSECS;after secs +!PREFERENCES_SQUAREDETAILWINDOW;Square detail window (faster) +!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_USESYSTEMTHEME; Use system theme +!PREFERENCES_WORKFLOW;Layout +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_SAVEPPASTE;Parameters to save +!PROGRESSBAR_BADPIXELS;Bad pixels... +!PROGRESSBAR_CACORRECTION;CA correction... +!PROGRESSBAR_DARKFRAME;Darkframe... +!PROGRESSBAR_GREENEQUIL;Green equilibrate... +!PROGRESSBAR_LINEDENOISE;Line Denoise... +!PROGRESSBAR_LOADINGTHUMBS;Loading thumbnails... +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing Profile Saved +!PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists +!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\nthe 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_CHROMATABERR_LABEL;Chromatic Aberration +!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_DETAIL_AMOUNT;Amount +!TP_DIRPYRDENOISE_CHROMA;Chrominance +!TP_DIRPYRDENOISE_GAMMA;Gamma +!TP_DIRPYRDENOISE_LABEL;Noise reduction +!TP_DIRPYRDENOISE_LUMA;Luminance +!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_EQUALIZER_CONTRAST_MINUS;Contrast- +!TP_EQUALIZER_CONTRAST_PLUS;Contrast+ +!TP_EQUALIZER_FINEST;finest +!TP_EQUALIZER_LABEL;Wavelet equalizer +!TP_EQUALIZER_LARGEST;coarsest +!TP_EQUALIZER_NEUTRAL;Neutral +!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 +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in auto levels operation +!TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Highlight recovery threshold +!TP_EXPOSURE_SATURATION;Saturation +!TP_EXPO_AFTER; After interpolation (before RGB conversion) +!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_HLREC_BLEND;Blend +!TP_HSVEQUALIZER_CHANNEL;HSV Channel +!TP_HSVEQUALIZER_HUE;H +!TP_HSVEQUALIZER_LABEL;HSV Equalizer +!TP_HSVEQUALIZER_NEUTRAL;Neutral +!TP_HSVEQUALIZER_SAT;S +!TP_HSVEQUALIZER_VAL;V +!TP_ICM_BLENDCMSMATRIX;Blend highlights with matrix +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover blown highlights when using LUT based ICC profiles +!TP_ICM_INPUTCAMERAICC;Auto-matched camera-specific color profile +!TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profile. These profiles are more precise than simpler matrix ones. Available for some 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_PREFERREDPROFILE;Preferred DCP profile +!TP_ICM_PREFERREDPROFILE_1;Daylight +!TP_ICM_PREFERREDPROFILE_2;Tungsten +!TP_ICM_PREFERREDPROFILE_3;Fluorescent +!TP_ICM_PREFERREDPROFILE_4;Flash +!TP_IMPULSEDENOISE_LABEL;Impulse Noise Reduction +!TP_IMPULSEDENOISE_THRESH;Impulse NR Threshold +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid Color Shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space\nand apply Munsell correction +!TP_LABCURVE_BRIGHTNESS;Brightness +!TP_LABCURVE_BWTONING;B&W Toning +!TP_LABCURVE_BWTONING_TIP;With B&W Toning option enabled, the Lab Chromaticity, Cc and Ch curves are not in effect.\nToning can be achieved using the a and b curves +!TP_LABCURVE_CHROMATICITY;Chromaticity +!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 the Chromaticity +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to the Hue +!TP_LABCURVE_LABEL;Lab Adjustments +!TP_LABCURVE_RSTPROTECTION;Red and Skin Tones Protection +!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;Use CA correction +!TP_LENSPROFILE_USEDIST;Use distortion correction +!TP_LENSPROFILE_USEVIGN;Use vignette correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset exposure controls to neutral values +!TP_PERSPECTIVE_HORIZONTAL;Horizontal +!TP_PERSPECTIVE_LABEL;Perspective +!TP_PERSPECTIVE_VERTICAL;Vertical +!TP_PREPROCESS_GREENEQUIL;Green equilibration +!TP_PREPROCESS_HOTDEADPIXFILT;Apply hot/dead pixel filter +!TP_PREPROCESS_HOTDEADPIXTHRESH;Hot/dead pixel detection threshold +!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 (leader) +!TP_RAWEXPOS_LINEAR;White Point: Linear corr. factor +!TP_RAWEXPOS_PRESER;White Point: HL preserving corr.(EV) +!TP_RAWEXPOS_TWOGREEN;Two greens together +!TP_RAW_ALLENHANCE;Apply post demosaic artifact/noise reduction +!TP_RAW_DCBENHANCE;Apply DCB enhancement step +!TP_RAW_DCBITERATIONS;Number of DCB iterations +!TP_RAW_DMETHOD;Method +!TP_RAW_FALSECOLOR;False color suppression steps +!TP_RAW_LABEL;Demosaicing +!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_RED;R +!TP_SHARPENEDGE_AMOUNT;Quantity +!TP_SHARPENEDGE_LABEL;Edges +!TP_SHARPENEDGE_PASSES;Iterations +!TP_SHARPENEDGE_THREE;Luminance only +!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 the Hue +!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_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 +!ZOOMPANEL_100;(100%) +!ZOOMPANEL_NEWCROPWINDOW;Open (new) detail window +!ZOOMPANEL_ZOOM100;Zoom to 100% 1 +!ZOOMPANEL_ZOOMFITSCREEN;Fit to screen F +!ZOOMPANEL_ZOOMIN;Zoom In + +!ZOOMPANEL_ZOOMOUT;Zoom Out - diff --git a/rtdata/languages/Chinese (Traditional) b/rtdata/languages/Chinese (Traditional) new file mode 100644 index 000000000..3c13c84df --- /dev/null +++ b/rtdata/languages/Chinese (Traditional) @@ -0,0 +1,1212 @@ +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_DIALOGLABEL;Exif Filter +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_ARRANGEMENTHINT;Change between vertical/horizontal alignment of thumbnails +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_EXIFFILTERAPPLYHINT;Switch on/off exif filter of the file browser +FILEBROWSER_EXIFFILTERAPPLY;Apply +FILEBROWSER_EXIFFILTERLABEL;Exif Filter +FILEBROWSER_EXIFFILTERSETTINGSHINT;Change settings of the exif filter +FILEBROWSER_EXIFFILTERSETTINGS;Setup +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_POPUPRANK1;Rank 1 +FILEBROWSER_POPUPRANK2;Rank 2 +FILEBROWSER_POPUPRANK3;Rank 3 +FILEBROWSER_POPUPRANK4;Rank 4 +FILEBROWSER_POPUPRANK5;Rank 5 +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_PROCESSINGSETTINGSHINT;Set the file format and output directory +FILEBROWSER_PROCESSINGSETTINGS;Settings +FILEBROWSER_RENAMEDLGLABEL;Rename file +FILEBROWSER_RENAMEDLGMSG;Rename file "%1" to: +FILEBROWSER_SHOWDIRHINT;Show all images of the directory +FILEBROWSER_SHOWQUEUEHINT;Show content of the processing queue +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_HIGH_QUALITY;High Quality +GENERAL_LANDSCAPE;橫向 +GENERAL_LOAD;載入 +GENERAL_NA;不適用 +GENERAL_NO;否 +GENERAL_OK;確定 +GENERAL_PORTRAIT;縱向 +GENERAL_SAVE;儲存存 +GENERAL_UNCHANGED;(Unchanged) +GENERAL_YES;是 +HISTOGRAM_LABEL;Histogram +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_NEWSNAPSHOTAS;為... +HISTORY_NEWSNAPSHOT;新建快照 +HISTORY_NEWSSDIALOGLABEL;快照標籤: +HISTORY_NEWSSDIALOGTITLE;添加新快照 +HISTORY_SETTO;設置為 +HISTORY_SNAPSHOTS;系列快照 +HISTORY_SNAPSHOT;快照 +ICMPANEL_FILEDLGFILTERANY;任意文件 +ICMPANEL_FILEDLGFILTERICM;ICC配置檔 +ICMPANEL_GAMMABEFOREINPUT;Profile applies Gamma +ICMPANEL_INPUTCAMERA;相機預設 +ICMPANEL_INPUTCUSTOM;自定義 +ICMPANEL_INPUTDLGLABEL;選擇輸入ICC配置... +ICMPANEL_INPUTEMBEDDED;如可能,使用內置 +ICMPANEL_INPUTPROFILE;輸入配置 +ICMPANEL_NOICM;No ICM: sRGB配置 +ICMPANEL_OUTPUTDLGLABEL;選擇輸出ICC配置... +ICMPANEL_OUTPUTPROFILE;輸出配置 +ICMPANEL_SAVEREFERENCE;Save reference image for profiling +ICMPANEL_WORKINGPROFILE;當前配置 +IMAGEAREA_DETAILVIEW;細節視圖 +IPTCPANEL_AUTHORHINT;Name of the creator of the object, e.g. writer, photographer or graphic artist (By-line). +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_EXIT;Exit +MAIN_BUTTON_PREFERENCES;參數設置 +MAIN_BUTTON_PUTTOQUEUE;Put to queue +MAIN_BUTTON_QUEUE;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_EXITJOBSINQUEUEINFO;Unprocessed images in the queue will be lost on exit. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Are you sure you want to exit? There are unprocessed images waiting in the queue. +MAIN_MSG_JOBSINQUEUE;任務列隊中 +MAIN_MSG_NAVIGATOR;Navigator +MAIN_MSG_PLACES;Places +MAIN_MSG_QOVERWRITE;是否覆蓋? +MAIN_TAB_BASIC;基本 +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_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;轉換 +MAIN_TOGGLE_BEFORE_AFTER;B|A +MAIN_TOOLTIP_HIDEFP;顯示/隱藏底部面板 (目錄和檔流覽器, shortcut key: F) +MAIN_TOOLTIP_HIDEHP;顯示/隱藏左面板 (包含歷史, shortcut key: H)) +MAIN_TOOLTIP_INDCLIPPEDH;高光溢出提示 +MAIN_TOOLTIP_INDCLIPPEDS;暗部不足提示 +MAIN_TOOLTIP_PREFERENCES;設置參數 +MAIN_TOOLTIP_QINFO;圖片快捷資訊 +MAIN_TOOLTIP_SAVEAS;圖片存於指定檔夾 +MAIN_TOOLTIP_SAVE;圖片存於預設檔夾 +MAIN_TOOLTIP_TOGGLE;Toggle before/after view +PARTIALPASTE_BASICGROUP;Basic settings +PARTIALPASTE_CACORRECTION;C/A correction +PARTIALPASTE_COARSETRANS;90 deg rotation / flipping +PARTIALPASTE_COLORBOOST;Color boost +PARTIALPASTE_COLORDENOISE;Color denoise +PARTIALPASTE_COLORGROUP;Color related settings +PARTIALPASTE_COLORMIXER;Color mixer +PARTIALPASTE_COLORSHIFT;Color shift +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_HLRECOVERY;Highlight recovery +PARTIALPASTE_ICMSETTINGS;ICM settings +PARTIALPASTE_IPTCINFO;IPTC info +PARTIALPASTE_LENSGROUP;Lens related settings +PARTIALPASTE_LUMACURVE;Luminance curve +PARTIALPASTE_LUMADENOISE;Luminance noise reduction +PARTIALPASTE_LUMINANCEGROUP;Luminance related settings +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_CACHESTRAT1;Prefer Speed to Low Memory Consumption +PREFERENCES_CACHESTRAT2;Prefer Low Memory Consumption to Speed +PREFERENCES_CACHESTRAT;Cache Strategy +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_DEMOSAICINGALGO;解拼演算法 +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_HINT;提示 +PREFERENCES_HLTHRESHOLD;高光溢出闕值 +PREFERENCES_ICCDIR;ICC配置路徑 +PREFERENCES_IMPROCPARAMS;預設圖片處理參數 +PREFERENCES_INTENT_ABSOLUTE;絕對色彩模式 +PREFERENCES_INTENT_PERCEPTUAL;感知模式 +PREFERENCES_INTENT_RELATIVE;相對色彩模式 +PREFERENCES_INTENT_SATURATION;飽和度 +PREFERENCES_LIVETHUMBNAILS;Live Thumbnails (slower) +PREFERENCES_MONITORICC;顯示器配置 +PREFERENCES_OUTDIRFOLDERHINT;Put the saved images to the seledted folder +PREFERENCES_OUTDIRFOLDER;Save to folder +PREFERENCES_OUTDIRHINT;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_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_SELECTICCDIRDLG;選擇ICC路徑... +PREFERENCES_SELECTLANG;選擇語言 +PREFERENCES_SELECTMONITORPROFDLG;選擇顯示器ICC路徑... +PREFERENCES_SELECTTHEME;Select theme +PREFERENCES_SHOWBASICEXIF;顯示基本Exif資訊 +PREFERENCES_SHOWDATETIME;顯示時間日期 +PREFERENCES_SHOWONLYRAW;僅顯示Raw檔 +PREFERENCES_SHTHRESHOLD;暗部不足闕值 +PREFERENCES_STARTUPIMDIR;啟動時路徑 +PREFERENCES_TAB_BROWSER;檔流覽器 +PREFERENCES_TAB_COLORMGR;色彩管理 +PREFERENCES_TAB_GENERAL;一般 +PREFERENCES_TAB_IMPROC;圖片處理 +PREFERENCES_TAB_OUTPUT;輸出選項 +PREFERENCES_THUMBSIZE;縮略圖大小 +PROFILEPANEL_FILEDLGFILTERANY;任意文件 +PROFILEPANEL_FILEDLGFILTERPP;處理參數配置 +PROFILEPANEL_LABEL;處理參數配置 +PROFILEPANEL_LOADDLGLABEL;載入處理參數為... +PROFILEPANEL_PCUSTOM;自定義 +PROFILEPANEL_PFILE;由文件 +PROFILEPANEL_PLASTPHOTO;上次圖片 +PROFILEPANEL_PLASTSAVED;上次儲存 +PROFILEPANEL_PROFILE;配置 +PROFILEPANEL_SAVEDLGLABEL;儲存處理參數為... +PROFILEPANEL_TOOLTIPCOPY;Copy current profile to clipboard +PROFILEPANEL_TOOLTIPLOAD;由檔載入配置 +PROFILEPANEL_TOOLTIPPASTE; Paste profile from clipboard +PROFILEPANEL_TOOLTIPSAVE;儲存當前配置 +PROGRESSBAR_DECODING;Raw檔解碼中... +PROGRESSBAR_DEMOSAICING;Raw檔解拼中... +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_FOCALLENGTH;焦距 +QINFO_ISO;ISO +QINFO_LENS;Lens +QINFO_NOEXIF;Exif資料不可用. +SAVEDLG_FILEFORMAT;檔格式 +SAVEDLG_JPEGQUAL;JPEG品質 +SAVEDLG_JPGFILTER;JPEG文件 +SAVEDLG_PNGCOMPR;PNG壓縮 +SAVEDLG_PNGFILTER;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_OUTPUTDLGLABEL;選擇輸出ICC配置... +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_LUMADENOISE_EDGETOLERANCE;邊緣容差 +TP_LUMADENOISE_LABEL;亮度噪點抑制 +TP_LUMADENOISE_RADIUS;半徑 +TP_RESIZE_BICUBICSF;雙三次 (柔化) +TP_RESIZE_BICUBICSH;雙三次 (銳化) +TP_RESIZE_BICUBIC;雙三次 +TP_RESIZE_BILINEAR;雙線性 +TP_RESIZE_FULLSIZE;全照片尺寸: +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;色溫 +ZOOMBAR_DETAIL;細節 +ZOOMBAR_HUGE;很大 +ZOOMBAR_LARGE;大 +ZOOMBAR_NORMAL;普通 +ZOOMBAR_PREVIEW;預覽 +ZOOMBAR_SCALE;比例 +ZOOMBAR_SMALL;小 + +#00 Chinese (Traditional) +#01 29.07.2008 +#02 Chinese Traditional +#03 Mingjui Liao + +!!!!!!!!!!!!!!!!!!!!!!!!! +! 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 +!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_SHARPENEDGE;Bypass Edge Sharpening +!EXPORT_BYPASS_SHARPENING;Bypass Sharpening +!EXPORT_BYPASS_SHARPENMICRO;Bypass Microcontrast +!EXPORT_BYPASS_SH_HQ;Bypass Shadow/Highlights (High Quality) +!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 the path text box.\nEnter / Ctrl-Enter (in the File Browser) to browse there;\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_CURRENT_NAME;Current name: +!FILEBROWSER_DARKFRAME;Dark frame +!FILEBROWSER_DELETEDLGMSGINCLPROC;Are you sure you want to delete the selected %1 files including a queue-processed version? +!FILEBROWSER_EXEC_CPB;Custom Profile Builder +!FILEBROWSER_EXTPROGMENU;Open with +!FILEBROWSER_FLATFIELD;Flat Field +!FILEBROWSER_MOVETODARKFDIR;Move to dark frames directory +!FILEBROWSER_MOVETOFLATFIELDDIR;Move to flat fields directory +!FILEBROWSER_NEW_NAME;New name: +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!FILEBROWSER_POPUPCOLORLABEL0;Label: None +!FILEBROWSER_POPUPCOLORLABEL1;Label: Red +!FILEBROWSER_POPUPCOLORLABEL2;Label: Yellow +!FILEBROWSER_POPUPCOLORLABEL3;Label: Green +!FILEBROWSER_POPUPCOLORLABEL4;Label: Blue +!FILEBROWSER_POPUPCOLORLABEL5;Label: Purple +!FILEBROWSER_POPUPCOLORLABEL;Color label +!FILEBROWSER_POPUPCOPYTO;Copy to... +!FILEBROWSER_POPUPFILEOPERATIONS;File Operations +!FILEBROWSER_POPUPMOVETO;Move to... +!FILEBROWSER_POPUPPROCESSFAST;Put to Queue (Fast export) +!FILEBROWSER_POPUPPROFILEOPERATIONS;Processing Profile Operations +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_POPUPREMOVESUBMENU;Remove +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!FILEBROWSER_QUERYHINT;Type a partial filename to search for.\nCtrl-F to focus the Find text box (in the File Browser).\nEnter to commence search. +!FILEBROWSER_QUERYLABEL; Find: +!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 +!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-` +!FILEBROWSER_USETEMPLATE;Use template: +!GENERAL_FILE;File +!GENERAL_NONE;None +!GENERAL_WARNING;Warning +!HISTOGRAM_BUTTON_BAR;RGB +!HISTOGRAM_BUTTON_B;B +!HISTOGRAM_BUTTON_G;G +!HISTOGRAM_BUTTON_L;L +!HISTOGRAM_BUTTON_RAW;Raw +!HISTOGRAM_BUTTON_R;R +!HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar\nClick right mouse button on image preview to freeze/unfreeze +!HISTOGRAM_TOOLTIP_FULL;Toggle full or scaled histogram +!HISTOGRAM_TOOLTIP_RAW;Show/Hide raw histogram +!HISTORY_MSG_82;Profile Changed +!HISTORY_MSG_83;High Quality Shadows/Highlights +!HISTORY_MSG_84;Perspective Correction +!HISTORY_MSG_85;Lens Correction Profile +!HISTORY_MSG_86;Wavelet Equalizer +!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 +!HISTORY_MSG_92;NR - Gamma +!HISTORY_MSG_93;Contrast by Detail Levels Value +!HISTORY_MSG_94;Contrast by Detail Levels +!HISTORY_MSG_95;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;RGB Saturation +!HISTORY_MSG_101;HSV EQ -- Hue +!HISTORY_MSG_102;HSV EQ -- Saturation +!HISTORY_MSG_103;HSV EQ -- Value +!HISTORY_MSG_104;HSV Equalizer +!HISTORY_MSG_105;Defringing +!HISTORY_MSG_106;Defringing Radius +!HISTORY_MSG_107;Defringing Threshold +!HISTORY_MSG_108;Highlight Compr. Threshold +!HISTORY_MSG_109;Resize Bounding Box +!HISTORY_MSG_110;Resizing applies o +!HISTORY_MSG_111;Avoid Color Shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;Red and Skin Tones Protection +!HISTORY_MSG_114;DCB Iterations +!HISTORY_MSG_115;False Color Iterations +!HISTORY_MSG_116;Enhanced DCB +!HISTORY_MSG_117;Red CA Correction +!HISTORY_MSG_118;Blue CA Correction +!HISTORY_MSG_119;Line Denoise +!HISTORY_MSG_120;Green Equil. Threshold +!HISTORY_MSG_121;Auto CA +!HISTORY_MSG_122;Auto Dark Frame +!HISTORY_MSG_123;Dark Frame File +!HISTORY_MSG_124;Linear Exp. Correction +!HISTORY_MSG_125;Exp. Correction Preserving HL +!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;Gamma +!HISTORY_MSG_134;Gamma Position +!HISTORY_MSG_135;Gamma Free +!HISTORY_MSG_136;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 Green Together +!HISTORY_MSG_142;Edges Sharpening - Iterations +!HISTORY_MSG_143;Edges Sharpening - Quantity +!HISTORY_MSG_144;Microcontrast - Quantity +!HISTORY_MSG_145;Microcontrast - Uniformity +!HISTORY_MSG_146;Edges Sharpening +!HISTORY_MSG_147;Edges Sharpening - 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;Vibrance - Pastel tones +!HISTORY_MSG_153;Vibrance - Saturated tones +!HISTORY_MSG_154;Vibrance - Protect skin tones +!HISTORY_MSG_155;Vibrance - Avoid color drift +!HISTORY_MSG_156;Vibrance - Link pastel and saturated tones +!HISTORY_MSG_157;Vibrance - Pastel/Saturated threshold +!HISTORY_MSG_158;Strength +!HISTORY_MSG_159;Edge Stopping +!HISTORY_MSG_160;Scale +!HISTORY_MSG_161;Reweighting Iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_163;RGB Curves - R +!HISTORY_MSG_164;RGB Curves - G +!HISTORY_MSG_165;RGB Curves - B +!HISTORY_MSG_166;Neutral Levels +!HISTORY_MSG_167;B&W Toning +!HISTORY_MSG_168;'Cc' curve +!HISTORY_MSG_169;'Ch' curve +!HISTORY_MSG_170;Vibrance - Curve +!MAIN_BUTTON_FULLSCREEN;Fullscreen +!MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Put current image to processing queue.\nShortcut: Ctrl+Q +!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_ERRORDURINGIMAGESAVING;Error during image saving +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue processed first. +!MAIN_TAB_COLOR_TOOLTIP;Shortcut: Alt-C +!MAIN_TAB_DETAIL_TOOLTIP;Shortcut: Alt-D +!MAIN_TAB_EXPORT; 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: 8 +!MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 0 +!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_CHANNELMIXER;Channel mixer +!PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto fill +!PARTIALPASTE_DARKFRAMEAUTOSELECT;Dark Frame Auto Select +!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;FF Auto Select +!PARTIALPASTE_FLATFIELDBLURRADIUS;FF Blur Radius +!PARTIALPASTE_FLATFIELDBLURTYPE;FF Blur Type +!PARTIALPASTE_FLATFIELDFILE;Flat field (FF) File +!PARTIALPASTE_HLRECONSTRUCTION;Highlight reconstruction +!PARTIALPASTE_HLRECOVERYAMOUNT;Highlight recovery amount +!PARTIALPASTE_HLRECOVERYTHRESHOLD;Highlight recovery threshold +!PARTIALPASTE_HSVEQUALIZER;HSV Equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!PARTIALPASTE_LABCURVE;Lab adjustments +!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 Level +!PARTIALPASTE_RAWEXPOS_LINEAR;Raw white point linear corr. factor +!PARTIALPASTE_RAWEXPOS_PRESER;Raw white point HL preserving corr. (EV) +!PARTIALPASTE_RAWGROUP;Raw settings +!PARTIALPASTE_RAW_ALLENHANCE;Apply post demosaic artifact/noise reduction +!PARTIALPASTE_RAW_DCBENHANCE;Apply DCB enhancement step +!PARTIALPASTE_RAW_DCBITERATIONS;Number of DCB iterations +!PARTIALPASTE_RAW_DMETHOD;Demosaic Method +!PARTIALPASTE_RAW_FALSECOLOR;Demosaic False color suppression steps +!PARTIALPASTE_RGBCURVES;RGB curves +!PARTIALPASTE_SHARPENEDGE;Edges +!PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_VIBRANCE;Vibrance +!PARTIALPASTE_WAVELETEQUALIZER;Wavelet equalizer +!PREFERENCES_ADD;ADD +!PREFERENCES_AUTOMONPROFILE;Automatically use operating system's main monitor color profile +!PREFERENCES_BATCH_PROCESSING;Batch Processing +!PREFERENCES_BEHAVIOR;Behavior +!PREFERENCES_CUSTPROFBUILDHINT;Executable (or script) file called when a new initial processing profile should be generated for an image.\nReceives command line parameters to allow a rules-based processing profile generation:\n[raw/JPG path] [default processing profile path] [f-number] [exposure in secs] [focal length in mm] [ISO] [lens] [camera] +!PREFERENCES_CUSTPROFBUILDPATH;Executable path +!PREFERENCES_CUSTPROFBUILD;Custom Processing Profile Builder +!PREFERENCES_CUTOVERLAYBRUSH;Crop mask color/transparency +!PREFERENCES_DARKFRAMEFOUND;Found +!PREFERENCES_DARKFRAMESHOTS;shots +!PREFERENCES_DARKFRAMETEMPLATES;templates +!PREFERENCES_DARKFRAME;Dark Frame +!PREFERENCES_DATEFORMATFRAME;Date Format +!PREFERENCES_DIRDARKFRAMES;Dark frames directory +!PREFERENCES_EDITORLAYOUT;Editor Layout +!PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar (de-select for low res display) +!PREFERENCES_FLATFIELDFOUND;Found +!PREFERENCES_FLATFIELDSDIR;Flat Fields directory +!PREFERENCES_FLATFIELDSHOTS;shots +!PREFERENCES_FLATFIELDTEMPLATES;templates +!PREFERENCES_FLATFIELD;Flat Field +!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_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). On Windows use "SystemDefault", "SystemAsterisk" etc. for system sounds. +!PREFERENCES_SND_LNGEDITPROCDONE;Editor processing done +!PREFERENCES_SND_TRESHOLDSECS;after secs +!PREFERENCES_SQUAREDETAILWINDOW;Square detail window (faster) +!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_USESYSTEMTHEME; Use system theme +!PREFERENCES_WORKFLOW;Layout +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_SAVEPPASTE;Parameters to save +!PROGRESSBAR_BADPIXELS;Bad pixels... +!PROGRESSBAR_CACORRECTION;CA correction... +!PROGRESSBAR_DARKFRAME;Darkframe... +!PROGRESSBAR_GREENEQUIL;Green equilibrate... +!PROGRESSBAR_LINEDENOISE;Line Denoise... +!PROGRESSBAR_LOADINGTHUMBS;Loading thumbnails... +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing Profile Saved +!PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists +!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\nthe 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_CHROMATABERR_LABEL;Chromatic Aberration +!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_CHROMA;Chrominance +!TP_DIRPYRDENOISE_GAMMA;Gamma +!TP_DIRPYRDENOISE_LABEL;Noise reduction +!TP_DIRPYRDENOISE_LUMA;Luminance +!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_EQUALIZER_CONTRAST_MINUS;Contrast- +!TP_EQUALIZER_CONTRAST_PLUS;Contrast+ +!TP_EQUALIZER_FINEST;finest +!TP_EQUALIZER_LABEL;Wavelet equalizer +!TP_EQUALIZER_LARGEST;coarsest +!TP_EQUALIZER_NEUTRAL;Neutral +!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 +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in auto levels operation +!TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Highlight recovery threshold +!TP_EXPOSURE_SATURATION;Saturation +!TP_EXPO_AFTER; After interpolation (before RGB conversion) +!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_HLREC_BLEND;Blend +!TP_HSVEQUALIZER_CHANNEL;HSV Channel +!TP_HSVEQUALIZER_HUE;H +!TP_HSVEQUALIZER_LABEL;HSV Equalizer +!TP_HSVEQUALIZER_NEUTRAL;Neutral +!TP_HSVEQUALIZER_SAT;S +!TP_HSVEQUALIZER_VAL;V +!TP_ICM_BLENDCMSMATRIX;Blend highlights with matrix +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover blown highlights when using LUT based ICC profiles +!TP_ICM_INPUTCAMERAICC;Auto-matched camera-specific color profile +!TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profile. These profiles are more precise than simpler matrix ones. Available for some 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_PREFERREDPROFILE;Preferred DCP profile +!TP_ICM_PREFERREDPROFILE_1;Daylight +!TP_ICM_PREFERREDPROFILE_2;Tungsten +!TP_ICM_PREFERREDPROFILE_3;Fluorescent +!TP_ICM_PREFERREDPROFILE_4;Flash +!TP_IMPULSEDENOISE_LABEL;Impulse Noise Reduction +!TP_IMPULSEDENOISE_THRESH;Impulse NR Threshold +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid Color Shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space\nand apply Munsell correction +!TP_LABCURVE_BRIGHTNESS;Brightness +!TP_LABCURVE_BWTONING;B&W Toning +!TP_LABCURVE_BWTONING_TIP;With B&W Toning option enabled, the Lab Chromaticity, Cc and Ch curves are not in effect.\nToning can be achieved using the a and b curves +!TP_LABCURVE_CHROMATICITY;Chromaticity +!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 the Chromaticity +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to the Hue +!TP_LABCURVE_LABEL;Lab Adjustments +!TP_LABCURVE_RSTPROTECTION;Red and Skin Tones Protection +!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;Use CA correction +!TP_LENSPROFILE_USEDIST;Use distortion correction +!TP_LENSPROFILE_USEVIGN;Use vignette correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset exposure controls to neutral values +!TP_PERSPECTIVE_HORIZONTAL;Horizontal +!TP_PERSPECTIVE_LABEL;Perspective +!TP_PERSPECTIVE_VERTICAL;Vertical +!TP_PREPROCESS_GREENEQUIL;Green equilibration +!TP_PREPROCESS_HOTDEADPIXFILT;Apply hot/dead pixel filter +!TP_PREPROCESS_HOTDEADPIXTHRESH;Hot/dead pixel detection threshold +!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 (leader) +!TP_RAWEXPOS_LINEAR;White Point: Linear corr. factor +!TP_RAWEXPOS_PRESER;White Point: HL preserving corr.(EV) +!TP_RAWEXPOS_TWOGREEN;Two greens together +!TP_RAW_ALLENHANCE;Apply post demosaic artifact/noise reduction +!TP_RAW_DCBENHANCE;Apply DCB enhancement step +!TP_RAW_DCBITERATIONS;Number of DCB iterations +!TP_RAW_DMETHOD;Method +!TP_RAW_FALSECOLOR;False color suppression steps +!TP_RAW_LABEL;Demosaicing +!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_RED;R +!TP_SHARPENEDGE_AMOUNT;Quantity +!TP_SHARPENEDGE_LABEL;Edges +!TP_SHARPENEDGE_PASSES;Iterations +!TP_SHARPENEDGE_THREE;Luminance only +!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 the Hue +!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_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 +!ZOOMPANEL_100;(100%) +!ZOOMPANEL_NEWCROPWINDOW;Open (new) detail window +!ZOOMPANEL_ZOOM100;Zoom to 100% 1 +!ZOOMPANEL_ZOOMFITSCREEN;Fit to screen F +!ZOOMPANEL_ZOOMIN;Zoom In + +!ZOOMPANEL_ZOOMOUT;Zoom Out - diff --git a/rtdata/languages/Czech b/rtdata/languages/Czech new file mode 100644 index 000000000..33f517bc8 --- /dev/null +++ b/rtdata/languages/Czech @@ -0,0 +1,1210 @@ +ABOUT_TAB_BUILD;Verze +ABOUT_TAB_CREDITS;Zásluhy +ABOUT_TAB_LICENSE;Licence +ABOUT_TAB_RELEASENOTES;Poznámky k vydání +ABOUT_TAB_SPLASH;Splash +ADJUSTER_RESET_TO_DEFAULT;Vrátit se k původnímu +BATCHQUEUE_AUTOSTART;Automatický start +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_DIALOGLABEL;Filtrovat dle Exif +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] rozšířené kroky 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_SHARPENEDGE;Vynechat doostření hran +EXPORT_BYPASS_SHARPENING;Vynechat doostření +EXPORT_BYPASS_SHARPENMICRO;Vynechat mikrokontrast +EXPORT_BYPASS_SH_HQ;Vynechat Světla/Stíny (vysoká kvalita) +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;Aplikovat profil +FILEBROWSER_APPLYPROFILE_PARTIAL;Aplikovat profil (částečně) +FILEBROWSER_ARRANGEMENTHINT;Přepnout mezi vertikálním/horizontálním zarovnáním náhledů +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 (v prohlížeči souborů) pro procházení ;\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;Vymazat profil +FILEBROWSER_COPYPROFILE;Kopírovat profil +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;Spustit vlastní generátor profilu +FILEBROWSER_EXIFFILTERAPPLYHINT;Zapnout/vypnout Exif filtr v prohlížeči souborů +FILEBROWSER_EXIFFILTERAPPLY;Použít +FILEBROWSER_EXIFFILTERLABEL;Filtrovat dle Exif +FILEBROWSER_EXIFFILTERSETTINGSHINT;Změnit nastavení Exif filtru +FILEBROWSER_EXIFFILTERSETTINGS;Nastavení +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 (zpracování fronty) +FILEBROWSER_PARTIALPASTEPROFILE;Vložit částečně +FILEBROWSER_PASTEPROFILE;Vložit profil +FILEBROWSER_POPUPCANCELJOB;Zrušit úlohu +FILEBROWSER_POPUPCOLORLABEL0;Štítek: Žádný +FILEBROWSER_POPUPCOLORLABEL1;Štítek: Červený +FILEBROWSER_POPUPCOLORLABEL2;Štítek: Žlutý +FILEBROWSER_POPUPCOLORLABEL3;Štítek: Zelený +FILEBROWSER_POPUPCOLORLABEL4;Štítek: Modrý +FILEBROWSER_POPUPCOLORLABEL5;Štítek: Růžový +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 s profily +FILEBROWSER_POPUPRANK1;Hodnocení 1 * +FILEBROWSER_POPUPRANK2;Hodnocení 2 ** +FILEBROWSER_POPUPRANK3;Hodnocení 3 *** +FILEBROWSER_POPUPRANK4;Hodnocení 4 **** +FILEBROWSER_POPUPRANK5;Hodnocení 5 ***** +FILEBROWSER_POPUPRANK;Hodnocení +FILEBROWSER_POPUPREMOVEINCLPROC;Smazat (včetně výstupů z fronty) +FILEBROWSER_POPUPREMOVESUBMENU;Smazat +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_PROCESSINGSETTINGSHINT;Nastavení formátu souboru a výstupní složky +FILEBROWSER_PROCESSINGSETTINGS;Nastavení +FILEBROWSER_QUERYBUTTONHINT;Smaže vyhledávací dotaz +FILEBROWSER_QUERYHINT;Napište část jména hledaného souboru a použijte \nCtrl-f k přepnutí do pole hledání (v Prohlížeči souborů).\nEnter ke spuštění hledání +FILEBROWSER_QUERYLABEL; Najít: +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 růžový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 +FILEBROWSER_SHOWQUEUEHINT;Ukázat obsah fronty zpracování +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-` +FILEBROWSER_SHOWUNRANKHINT;Ukázat nehodnocené obrázky.\nZkratka: ` +FILEBROWSER_STARTPROCESSINGHINT;Spustit zpracování nebo ukládání obrázků ve frontě +FILEBROWSER_STARTPROCESSING;Spustit zpracování +FILEBROWSER_STOPPROCESSINGHINT;Zastavit zpracovávaní obrázků +FILEBROWSER_STOPPROCESSING;Zastavit zpracovávaní +FILEBROWSER_THUMBSIZE;Velikost náhledů +FILEBROWSER_TOOLTIP_STOPPROCESSING;Automatické spuštění zpracování po vložení nové úlohy +FILEBROWSER_USETEMPLATE;Použít šablonu: +FILEBROWSER_ZOOMINHINT;Zvětšit velikosti náhledů.\nZkratka: + +FILEBROWSER_ZOOMOUTHINT;Zmenšit velikosti náhledů.\nZkratka: - +GENERAL_ABOUT;O programu +GENERAL_AFTER;Poté +GENERAL_BEFORE;Před +GENERAL_CANCEL;Zrušit +GENERAL_DISABLED;Vypnuto +GENERAL_DISABLE;Vypnout +GENERAL_ENABLED;Zapnuto +GENERAL_ENABLE;Zapnout +GENERAL_FILE;Soubor +GENERAL_HIGH_QUALITY;Vysoká kvalita +GENERAL_LANDSCAPE;Na šířku +GENERAL_LOAD;Načíst +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_YES;Ano +HISTOGRAM_BUTTON_BAR;RGB +HISTOGRAM_BUTTON_B;B +HISTOGRAM_BUTTON_G;G +HISTOGRAM_BUTTON_L;L +HISTOGRAM_BUTTON_RAW;Raw +HISTOGRAM_BUTTON_R;R +HISTOGRAM_LABEL;Histogram +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_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;Profil načten +HISTORY_MSG_3;Profil změněn +HISTORY_MSG_4;Prohlížení historie +HISTORY_MSG_5;Jas +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 +HISTORY_MSG_12;Automatická expozice +HISTORY_MSG_13;Oříznutí expozice +HISTORY_MSG_14;Zářivost jasu +HISTORY_MSG_15;Jas 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;Poloměr doostření +HISTORY_MSG_22;Míra doostření +HISTORY_MSG_23;Práh doostření +HISTORY_MSG_24;Doostření pouze v okrajích +HISTORY_MSG_25;Poloměr detekce okrajů při doostření +HISTORY_MSG_26;Tolerance okrajů při doostření +HISTORY_MSG_27;Omezení haló artefaktů při doostření +HISTORY_MSG_28;Míra omezení haló artefaktů +HISTORY_MSG_29;Metoda doostření +HISTORY_MSG_30;Poloměr dekonvoluce +HISTORY_MSG_31;Míra dekonvoluce +HISTORY_MSG_32;Útlum dekonvoluce +HISTORY_MSG_33;Počet průchodů dekonvoluce +HISTORY_MSG_34;Zabránit oříznutí barev +HISTORY_MSG_35;Povolit omezení saturace +HISTORY_MSG_36;Omezení saturace +HISTORY_MSG_37;Sytost barev +HISTORY_MSG_38;Metoda vyvážení bílé +HISTORY_MSG_39;Barevná teplota +HISTORY_MSG_40;Odstín vyvážení bílé +HISTORY_MSG_41;Barevný posun "A" +HISTORY_MSG_42;Barevný posun "B" +HISTORY_MSG_43;Jas Redukce šumu +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;Poloměr redukce barevného šumu +HISTORY_MSG_48;Okrajová tolerance v redukci barevného šumu +HISTORY_MSG_49;Redukce barevného šumu s ohledem na okraje +HISTORY_MSG_50;Nástroj Stíny/světla +HISTORY_MSG_51;Propagace světel +HISTORY_MSG_52;Zvýraznění stínů +HISTORY_MSG_53;Tónový rozsah světel +HISTORY_MSG_54;Tónový rozsah stínů +HISTORY_MSG_55;Místní kontrast +HISTORY_MSG_56;Poloměr světel a stínů +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;Úprava zkreslení objektivu +HISTORY_MSG_63;Snímek vybrán +HISTORY_MSG_64;Oříznout fotku +HISTORY_MSG_65;Úprava chromatické vady +HISTORY_MSG_66;Obnovení světel +HISTORY_MSG_67;Míra obnovení světel +HISTORY_MSG_68;Metoda obnovení světel +HISTORY_MSG_69;Pracovní barevný prostor +HISTORY_MSG_70;Výstupní barevný prostor +HISTORY_MSG_71;Vstupní barevný prostor +HISTORY_MSG_72;Úprava vinětace +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 rozměrů povolena +HISTORY_MSG_82;Profil změněn +HISTORY_MSG_83;Vysoká kvalita světel/stínů +HISTORY_MSG_84;Korekce perspektivy +HISTORY_MSG_85;Vlnkové koeficienty +HISTORY_MSG_86;Vlnková korekce +HISTORY_MSG_87;Redukce impulzního šumu +HISTORY_MSG_88;Práh +HISTORY_MSG_89;Redukce šumu +HISTORY_MSG_90;Redukce šumu - jas +HISTORY_MSG_91;Redukce šumu - barevnost +HISTORY_MSG_92;Redukce šumu - gama +HISTORY_MSG_93;Kontrast dle detailu úrovní - hodnota +HISTORY_MSG_94;Kontrast dle detailu úrovní +HISTORY_MSG_95;Sytost +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 RGB +HISTORY_MSG_101;HSV korekce -- Odstín +HISTORY_MSG_102;HSV korekce -- Sytost +HISTORY_MSG_103;HSV korekce -- Hodnota +HISTORY_MSG_104;HSV korekce +HISTORY_MSG_105;Odstranění lemu +HISTORY_MSG_106;Odstranění lemu poloměr +HISTORY_MSG_107;Odstranění 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;Zabránit oříznutí barev +HISTORY_MSG_112;Povolit omezení saturace +HISTORY_MSG_113;Omezení saturace +HISTORY_MSG_114;Průchody DCB +HISTORY_MSG_115;Průchody chybných barev +HISTORY_MSG_116;Rozšířené DCB +HISTORY_MSG_117;Korekce červené CA +HISTORY_MSG_118;Korekce modré CA +HISTORY_MSG_119;Linkové odšumění +HISTORY_MSG_120;Práh vyrovnání zelené +HISTORY_MSG_121;Automatická CA +HISTORY_MSG_122;Automatický tmavý snímek +HISTORY_MSG_123;Soubor tmavého snímku +HISTORY_MSG_124;Lineární expoziční korekce +HISTORY_MSG_125;Expoziční korekce zachování jasu +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 chromatického šumu +HISTORY_MSG_133;Gama +HISTORY_MSG_134;Pozice gamy +HISTORY_MSG_135;Volná gama +HISTORY_MSG_136;Sklon 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é: Zelené zároveň +HISTORY_MSG_142;Doostření hran - počet průchodů +HISTORY_MSG_143;Doostření hran - kvalita +HISTORY_MSG_144;Mikrokontrast - kvantita +HISTORY_MSG_145;Mikrokontrast - jednolitost +HISTORY_MSG_146;Doostření hran +HISTORY_MSG_147;Doostření hran - 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 - zachovat tóny pleti +HISTORY_MSG_155;Živost - Vyvarovat se posunu barev +HISTORY_MSG_156;Živost - propojit pastelové a saturované tóny +HISTORY_MSG_157;Živost - práh mezi pastelovými a saturovanými tóny +HISTORY_MSG_158;Síla +HISTORY_MSG_159;Míra zachování hran +HISTORY_MSG_160;Měřítko +HISTORY_MSG_161;Počet průchodů převážení +HISTORY_MSG_162;Mapování tónů +HISTORY_MSG_163;RGB křivky - R +HISTORY_MSG_164;RGB křivky - G +HISTORY_MSG_165;RGB křivky - B +HISTORY_MSG_166;Neutrální úrovně +HISTORY_NEWSNAPSHOTAS;Jako... +HISTORY_NEWSNAPSHOT;Přidat +HISTORY_NEWSSDIALOGLABEL;Titulek snímku: +HISTORY_NEWSSDIALOGTITLE;Přidat nový snímek +HISTORY_SETTO;Nastavit na +HISTORY_SNAPSHOTS;Snímky +HISTORY_SNAPSHOT;Snímek +ICMPANEL_FILEDLGFILTERANY;Jakékoliv soubory +ICMPANEL_FILEDLGFILTERICM;Soubory ICC profilů +ICMPANEL_GAMMABEFOREINPUT;Profil aplikuje Gama korekci +ICMPANEL_INPUTCAMERA;Výchozí fotoaparátu +ICMPANEL_INPUTCUSTOM;Vlastní +ICMPANEL_INPUTDLGLABEL;Vybrat vstupní ICC profil... +ICMPANEL_INPUTEMBEDDED;Použít vložený profil, pokud je k dispozici +ICMPANEL_INPUTPROFILE;Vstupní profil +ICMPANEL_NOICM;Bez ICM: sRGB výstup +ICMPANEL_OUTPUTDLGLABEL;Vybrat výstupní ICC profil... +ICMPANEL_OUTPUTPROFILE;Výstupní barevný prostor +ICMPANEL_SAVEREFERENCE;Uložit referenční obrázek pro profilování +ICMPANEL_WORKINGPROFILE;Pracovní barevný prostor +IMAGEAREA_DETAILVIEW;Detailní pohled +IPTCPANEL_AUTHORHINT;Jméno autora, například spisovatele, fotografa nebo grafika (By-line). +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;Kdy byl obrázek 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_EXIT;Konec +MAIN_BUTTON_FULLSCREEN;Celá obrazovka +MAIN_BUTTON_PREFERENCES;Volby +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Vložit současný obrázek do fronty zpracování.\nZkratka: Ctrl+Q +MAIN_BUTTON_QUEUE;Vložit do fronty +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_ERRORDURINGIMAGESAVING;Chyba při ukládání obrázku +MAIN_MSG_EXITJOBSINQUEUEINFO;Nezpracované obrázky ve frontě budou při ukončení ztraceny. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Opravdu chcete skončit? Ve frontě čekají nezpracované obrázky. +MAIN_MSG_IMAGEUNPROCESSED;Tento příkaz vyžaduje aby byly všechny vybrané obrázky nejprve zpracovány ve frontě. +MAIN_MSG_JOBSINQUEUE;úlohy ve frontě +MAIN_MSG_NAVIGATOR;Navigátor +MAIN_MSG_PLACES;Místa +MAIN_MSG_QOVERWRITE;Chcete jej přepsat? +MAIN_TAB_BASIC;Základní +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;Export +MAIN_TAB_EXPOSURE;Expozice +MAIN_TAB_EXPOSURE_TOOLTIP;Zkratka: Alt-E +MAIN_TAB_FILTER;Filtr +MAIN_TAB_ICM;ICM +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_TOGGLE_BEFORE_AFTER;Před|Po +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_HIDEFP;Zobrazit či schovat dolní panel (složky a prohlížeč souborů).\nZkratka: F +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_PREFERENCES;Změnit volby +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ětlosti.\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_SAVEAS;Uložit obrázek do zadané složky +MAIN_TOOLTIP_SAVE;Uložit obrázek do výchozí složky +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_NA;x = n/a, y = n/a +PARTIALPASTE_BASICGROUP;Základní nastavení +PARTIALPASTE_CACORRECTION;Úprava chromatické vady +PARTIALPASTE_CHANNELMIXER;Míchání kanálů +PARTIALPASTE_COARSETRANS;Rotace o 90° / překlopení +PARTIALPASTE_COLORBOOST;Posílení barev +PARTIALPASTE_COLORDENOISE;Odstranění barevného šumu +PARTIALPASTE_COLORGROUP;Nastavení barev +PARTIALPASTE_COLORMIXER;Míchání barev +PARTIALPASTE_COLORSHIFT;Posun 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;Upravená exif data +PARTIALPASTE_EXPOSURE;Expozice +PARTIALPASTE_FLATFIELDAUTOSELECT;FF Automatický výběr +PARTIALPASTE_FLATFIELDBLURRADIUS;FF Poloměr rozostření +PARTIALPASTE_FLATFIELDBLURTYPE;FF Typ rozostření +PARTIALPASTE_FLATFIELDFILE;Flat Field (FF) Soubor +PARTIALPASTE_HLRECONSTRUCTION;Rekonstrukce světel +PARTIALPASTE_HLRECOVERYAMOUNT;Míra obnovení světel +PARTIALPASTE_HLRECOVERYTHRESHOLD;Práh obnovení světel +PARTIALPASTE_HLRECOVERY;Obnovení světel +PARTIALPASTE_HSVEQUALIZER;HSV korekce +PARTIALPASTE_ICMGAMMA;Výstupní gama +PARTIALPASTE_ICMSETTINGS;Nastavení ICM +PARTIALPASTE_IMPULSEDENOISE;Redukce impulzního šumu +PARTIALPASTE_IPTCINFO;IPTC info +PARTIALPASTE_LABCURVE;Úprava LAB křivek +PARTIALPASTE_LENSGROUP;Nastavení objektivu +PARTIALPASTE_LUMADENOISE;Redukce šumu v jasech +PARTIALPASTE_LUMINANCEGROUP;Nastavení jasu +PARTIALPASTE_METAICMGROUP;Nastavení metadat a ICM +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;Chromatická aberace - modrá +PARTIALPASTE_RAWCACORR_CARED;Chromatická aberace - červená +PARTIALPASTE_RAWEXPOS_BLACK;Úrovně černé +PARTIALPASTE_RAWEXPOS_LINEAR;Faktor lineární korekce Raw bílého bodu +PARTIALPASTE_RAWEXPOS_PRESER;Korekce zach. Raw bílého bodu (EV) +PARTIALPASTE_RAWGROUP;Nastavení Raw +PARTIALPASTE_RAW_ALLENHANCE;Aplikovat redukci artefaktů/šumu po demozajkování +PARTIALPASTE_RAW_DCBENHANCE;Aplikovat kroky rozšířeného 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_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_WAVELETEQUALIZER;Vlnková korekce +PARTIALPASTE_WHITEBALANCE;Nastavení bílé +PREFERENCES_ADD;Přidat +PREFERENCES_APPLNEXTSTARTUP;vyžaduje restart aplikace +PREFERENCES_AUTOMONPROFILE;Automaticky použít hlavní profil monitoru z operačního systému. +PREFERENCES_BATCH_PROCESSING;Dávkové zpracování +PREFERENCES_BEHAVIOR;Režim +PREFERENCES_BLINKCLIPPED;Blikání v oříznutých oblastech +PREFERENCES_CACHECLEARALL;Vymazat vše +PREFERENCES_CACHECLEARPROFILES;Vymazat profily +PREFERENCES_CACHECLEARTHUMBS;Vymazat náhledy +PREFERENCES_CACHEFORMAT1;Vlastní (rychlejší a kvalitnější) +PREFERENCES_CACHEFORMAT2;JPEG (menší velikost) +PREFERENCES_CACHEMAXENTRIES;Maximální počet záznamů v cache +PREFERENCES_CACHEOPTS;Vlastnosti cache +PREFERENCES_CACHESTRAT1;Upřednostnit rychlost před spotřebou paměti +PREFERENCES_CACHESTRAT2;Upřednostnit nižší spotřebu paměti před rychlostí +PREFERENCES_CACHESTRAT;Strategie cache +PREFERENCES_CACHETHUMBFORM;Formát náhledů v cache +PREFERENCES_CACHETHUMBHEIGHT;Maximální výška náhledu +PREFERENCES_CLIPPINGIND;Indikace oříznutí +PREFERENCES_CMETRICINTENT;Kolorimetrická metoda +PREFERENCES_CUSTPROFBUILDHINT;Program (nebo skript) spuštěný v případě, že má být vygenerován nový profil pro obrázek.\nBude spuštěn s následujícími parametry, které umožní vygenerování vhodného .pp3 profilu:\n[Cesta raw/JPG] [Výchozí cesta profilu] [Clona] [Expozice v sekundách] [Ohnisková vzdálenost v mm] [ISO] [Objektiv] [Fotoaparát] +PREFERENCES_CUSTPROFBUILDPATH;Cesta k programu +PREFERENCES_CUSTPROFBUILD;Vlastní generátor profilu obrázku +PREFERENCES_CUTOVERLAYBRUSH;Barva masky ořezu/průhlednosti +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_DEMOSAICINGALGO;Demozajkovací algoritmus +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_FORIMAGE;Pro obrázkové soubory +PREFERENCES_FORRAW;Pro raw soubory +PREFERENCES_GIMPPATH;GIMP instalační složka +PREFERENCES_GTKTHEME;GTK výchozí +PREFERENCES_HINT;Nápověda +PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogram v levém panelu +PREFERENCES_HLTHRESHOLD;Práh oříznutých světel +PREFERENCES_ICCDIR;Složka ICC profilů +PREFERENCES_IMPROCPARAMS;Výchozí profily pro 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 interní raw náhledy u needitovaných snímků +PREFERENCES_LANGAUTODETECT;Použít jazykové nastavení OS +PREFERENCES_LIVETHUMBNAILS;Živé náhledy (pomalejší) +PREFERENCES_MENUGROUPEXTPROGS;Seskupit "Otevřít pomocí" +PREFERENCES_MENUGROUPFILEOPERATIONS;Seskupit souborové operace +PREFERENCES_MENUGROUPLABEL;Seskupit značení +PREFERENCES_MENUGROUPPROFILEOPERATIONS;Seskupit operace s profily +PREFERENCES_MENUGROUPRANK;Seskupit hodnocení +PREFERENCES_MENUOPTIONS;Vlastnosti nabídky +PREFERENCES_METADATA;Metadata +PREFERENCES_MONITORICC;Profil monitoru +PREFERENCES_MULTITABDUALMON;Mód více karet; pouze pokud je dostupný druhý monitor +PREFERENCES_MULTITAB;Mód více karet +PREFERENCES_OUTDIRFOLDERHINT;Uložit obrázky do vybrané složky +PREFERENCES_OUTDIRFOLDER;Ulož do souboru +PREFERENCES_OUTDIRHINT;Lze použít následující formátovací řetězce:\n%f, %d1, %d2, ..., %p1, %p2, ..., %r\n\nTyto formátovací řetězce reprezentují různé části cesty k uložené fotografii.\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\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 "converted" ve stejném adresáři jako otevřený obrázek, napište:\n%p1/converted/%f\n\nPro uložení výstupního obrázku do adresáře "/home/tom/photos/converted/2010-10-31", napište:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATEHINT;Lze použít následující formátovací řetězce:\n%f, %d1, %d2, ..., %p1, %p2, ..., %r\n\nTyto formátovací řetězce reprezentují různé části cesty k uložené fotografii.\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\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 "converted" ve stejném adresáři jako otevřený obrázek, napište:\n%p1/converted/%f\n\nPro uložení výstupního obrázku do adresáře "/home/tom/photos/converted/2010-10-31", napište:\n%p2/converted/%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í profilu +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í se zdrojovým souborem +PREFERENCES_PROPERTY;Vlastnost +PREFERENCES_PSPATH;Instalační složka Adobe Photoshop +PREFERENCES_SELECTFONT;Vybrat písmo +PREFERENCES_SELECTICCDIRDLG;Zvolit složku s ICC profily... +PREFERENCES_SELECTLANG;Volba jazyka +PREFERENCES_SELECTMONITORPROFDLG;Zvolit ICC profil obrazovky... +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_SHOWONLYRAW;Zobrazovat pouze soubory raw +PREFERENCES_SHOWPROFILESELECTOR;Zobrazit výběr profilu +PREFERENCES_SHTHRESHOLD;Práh oříznutých stínů +PREFERENCES_SINGLETABVERTAB;Mód jedné karty, svislé karty +PREFERENCES_SINGLETAB;Mód jedné karty +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). Ve Windows zadejte "SystemDefault", "SystemAsterisk", atd. pro použití systémových zvuků. +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_OUTPUT;Volby výstupu +PREFERENCES_TAB_SOUND;Zvuky +PREFERENCES_THUMBSIZE;Velikost náhledu +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_USESYSTEMTHEME; Použít systémový motiv +PREFERENCES_WORKFLOW;Rozvržení +PROFILEPANEL_COPYPPASTE;Parametry pro kopírování +PROFILEPANEL_FILEDLGFILTERANY;Jakékoliv soubory +PROFILEPANEL_FILEDLGFILTERPP;Profily zpracování +PROFILEPANEL_LABEL;Profily zpracování +PROFILEPANEL_LOADDLGLABEL;Načíst parametry zpracování... +PROFILEPANEL_LOADPPASTE;Parametry nahrávání +PROFILEPANEL_PASTEPPASTE;Parametry pro vložení +PROFILEPANEL_PCUSTOM;Vlastní +PROFILEPANEL_PFILE;Ze souboru +PROFILEPANEL_PLASTPHOTO;Poslední fotka +PROFILEPANEL_PLASTSAVED;Poslední uschovaný +PROFILEPANEL_PROFILE;Profil +PROFILEPANEL_SAVEDLGLABEL;Uschovat 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_BADPIXELS;Špatné pixely +PROGRESSBAR_CACORRECTION;Korekce chromatické aberace... +PROGRESSBAR_DARKFRAME;Tmavý snímek... +PROGRESSBAR_DECODING;Dekódování raw... +PROGRESSBAR_DEMOSAICING;Demozajkování... +PROGRESSBAR_GREENEQUIL;Vyrovnání zelené... +PROGRESSBAR_LINEDENOISE;Linkové odšumění... +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_PROCESSING;Zpracovávaní obrázku... +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... +PROGRESSDLG_PROFILECHANGEDINBROWSER;Změněn profil v prohlížeči +QINFO_FOCALLENGTH;Ohnisková vzdálenost +QINFO_ISO;ISO +QINFO_LENS;Objektiv +QINFO_NOEXIF;Exif údaje nejsou k dispozici. +SAVEDLG_AUTOSUFFIX;Automaticky přidat příponu pokud soubor již existuje +SAVEDLG_FILEFORMAT;Formát souboru +SAVEDLG_JPEGQUAL;Kvalita JPEG +SAVEDLG_JPGFILTER;Soubory JPEG +SAVEDLG_PNGCOMPR;PNG Komprese +SAVEDLG_PNGFILTER;Soubory PNG +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_TIFFFILTER;Soubory TIFF +SAVEDLG_TIFFUNCOMPRESSED;Nekomprimovaný TIFF +TOOLBAR_TOOLTIP_CROP;Vyznačení výřezu.\nZkratka: c +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_CACORRECTION_BLUE;Modrá +TP_CACORRECTION_LABEL;Úprava chromatické vady +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_DEGREE;Stupeň: +TP_COARSETRAF_TOOLTIP_HFLIP;Překlopit horizontálně +TP_COARSETRAF_TOOLTIP_ROTLEFT;Otočit doleva +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Otočit doprava +TP_COARSETRAF_TOOLTIP_VFLIP;Překlopit vertikálně +TP_COLORBOOST_ACHANNEL;Kanál "a" +TP_COLORBOOST_AMOUNT;Míra +TP_COLORBOOST_AVOIDCOLORCLIP;Zabránit oříznutí barvy +TP_COLORBOOST_BCHANNEL;Kanál "b" +TP_COLORBOOST_CHANNEL;Kanál +TP_COLORBOOST_CHSEPARATE;zvlášť +TP_COLORBOOST_ENABLESATLIMITER;Omezovat sytost +TP_COLORBOOST_LABEL;Sytost barev +TP_COLORBOOST_SATLIMIT;Limit sytosti +TP_COLORDENOISE_EDGESENSITIVE;Citlivost k okrajům +TP_COLORDENOISE_EDGETOLERANCE;Tolerance okrajům +TP_COLORDENOISE_LABEL;Redukce barevného šumu +TP_COLORDENOISE_RADIUS;Poloměr +TP_COLORSHIFT_BLUEYELLOW;Modrá-Žlutá +TP_COLORSHIFT_GREENMAGENTA;Modrá-Purpurová +TP_COLORSHIFT_LABEL;Barevný posun +TP_CROP_FIXRATIO;Poměr stran: +TP_CROP_GTDIAGONALS;Pravidlo diagonál +TP_CROP_GTEPASSPORT;Biometrický pas +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 +TP_CROP_LABEL;Ořez +TP_CROP_PPI;PPI= +TP_CROP_SELECTCROP; Vyznačit výřez +TP_CROP_W;Š +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_DETAIL_AMOUNT;Míra +TP_DIRPYRDENOISE_CHROMA;Barevnost +TP_DIRPYRDENOISE_GAMMA;Gama +TP_DIRPYRDENOISE_LABEL;Redukce šumu +TP_DIRPYRDENOISE_LUMA;Jas +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í objektivu +TP_DISTORTION_AUTO_TIP;(Experimentální) Automatická korekce zkreslení objektivu pro některé fotoaparáty (M4/3, některé kompakty a jiné). +TP_DISTORTION_LABEL;Oprava zkreslení objektivu +TP_EPD_EDGESTOPPING;Zachování okrajů +TP_EPD_LABEL;Mapování tónů +TP_EPD_REWEIGHTINGITERATES;Počet průchodů převážení +TP_EPD_SCALE;Měřítko +TP_EPD_STRENGTH;Síla +TP_EQUALIZER_CONTRAST_MINUS;Kontrast- +TP_EQUALIZER_CONTRAST_PLUS;Kontrast+ +TP_EQUALIZER_FINEST;Nejjemnější +TP_EQUALIZER_LABEL;Vlnková korekce +TP_EQUALIZER_LARGEST;Nejhrubší +TP_EQUALIZER_NEUTRAL;Neutrální +TP_EXPOSCORR_LABEL;Raw bílý-černý bod +TP_EXPOSURE_AUTOLEVELS;Úrovně automaticky +TP_EXPOSURE_AUTOLEVELS_TIP;Přepne provedení automatických úrovní na automatickou sadu hodnot parametrů založených na analýze obrázku +TP_EXPOSURE_BLACKLEVEL;Černá +TP_EXPOSURE_BRIGHTNESS;Jas +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 obnovení světel +TP_EXPOSURE_COMPRHIGHLIGHTS;Míra obnovení světel +TP_EXPOSURE_COMPRSHADOWS;Komprese stínů +TP_EXPOSURE_CONTRAST;Kontrast +TP_EXPOSURE_CURVEEDITOR;Tónová křivka +TP_EXPOSURE_EXPCOMP;Kompenzace expozice +TP_EXPOSURE_LABEL;Expozice +TP_EXPOSURE_SATURATION;Sytost +TP_EXPO_AFTER; Po interpolaci (před RGB konverzí) +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;Vod. 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_HLREC_BLEND;Mísení +TP_HLREC_CIELAB;Mísení CIELab +TP_HLREC_COLOR;Propagace barev +TP_HLREC_LABEL;Rekonstrukce světel +TP_HLREC_LUMINANCE;Obnovení jasů +TP_HLREC_METHOD;Metoda: +TP_HSVEQUALIZER_CHANNEL;HSV kanál +TP_HSVEQUALIZER_HUE;H +TP_HSVEQUALIZER_LABEL;HSV korekce +TP_HSVEQUALIZER_NEUTRAL;Neutrální +TP_HSVEQUALIZER_SAT;S +TP_HSVEQUALIZER_VAL;V +TP_ICM_BLENDCMSMATRIX;Smísit světla a matici +TP_ICM_BLENDCMSMATRIX_TOOLTIP;Povolit obnovení vypálených jasů při použití ICC profilů založených na LUT +TP_ICM_FILEDLGFILTERANY;Jakékoliv soubory +TP_ICM_FILEDLGFILTERICM;Soubory profilů +TP_ICM_INPUTCAMERAICC;Automatický dohledaný specifický profil fotoaparátu +TP_ICM_INPUTCAMERAICC_TOOLTIP;Použít RawTherapee specifický DCP nebo ICC vstupní profil fotoaparátu jenž je mnohem přesnější než zjednodušená matice. Dostupné pro některé fotoaparáty. Profily jsou uloženy ve složce /iccprofiles/input 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 verzí 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 ne-raw 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 správy barev: sRGB výstup +TP_ICM_OUTPUTDLGLABEL;Vybrat výstupní ICC profil... +TP_ICM_OUTPUTPROFILE;Výstupní barevný prostor +TP_ICM_PREFERREDPROFILE;Preferovaný DCP profil +TP_ICM_PREFERREDPROFILE_1;Denní světlo +TP_ICM_PREFERREDPROFILE_2;Wolfram +TP_ICM_PREFERREDPROFILE_3;Fluorescenční +TP_ICM_PREFERREDPROFILE_4;Blesk +TP_ICM_SAVEREFERENCE;Uložit referenční obrázek pro profilování +TP_ICM_WORKINGPROFILE;Pracovní barevný prostor +TP_IMPULSEDENOISE_LABEL;Redukce impulzního šumu +TP_IMPULSEDENOISE_THRESH;Práh +TP_LABCURVE_AVOIDCOLORCLIP;Zabránit oříznutí barvy +TP_LABCURVE_BRIGHTNESS;Jas +TP_LABCURVE_CONTRAST;Kontrast +TP_LABCURVE_CURVEEDITOR;Křivka jasů +TP_LABCURVE_ENABLESATLIMITER;Omezovat sytost +TP_LABCURVE_LABEL;Úprava LAB křivek +TP_LABCURVE_SATLIMIT;Limit sytosti +TP_LABCURVE_SATURATION;Sytost +TP_LENSGEOM_AUTOCROP; Automatický ořez +TP_LENSGEOM_FILL;Automatické vyplnění +TP_LENSGEOM_LABEL;Objektiv / Geometrie +TP_LUMADENOISE_EDGETOLERANCE;Tolerance okrajům +TP_LUMADENOISE_LABEL;Redukce šumu v jasech +TP_LUMADENOISE_RADIUS;Poloměr +TP_NEUTRAL;Neutrální +TP_NEUTRAL_TIP;Vrátí nastavení expozice na neutrální hodnoty +TP_PERSPECTIVE_HORIZONTAL;Vodorovně +TP_PERSPECTIVE_LABEL;Perspektiva +TP_PERSPECTIVE_VERTICAL;Svisle +TP_PREPROCESS_GREENEQUIL;Vyrovnání zelené +TP_PREPROCESS_HOTDEADPIXFILT;Aplikovat filtr na vypálené/mrtvé body +TP_PREPROCESS_HOTDEADPIXTHRESH;Práh filtru vypálených/mrtvých pixelů +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;Bílý bod: Faktor lineární korekce +TP_RAWEXPOS_PRESER;Bílý bod: Kor. zachování světel (EV) +TP_RAWEXPOS_TWOGREEN;Obě zelené zároveň +TP_RAW_ALLENHANCE;Aplikovat redukci artefaktů/šumu po demozajkování +TP_RAW_DCBENHANCE;Aplikovat kroky rozšířeného DCB +TP_RAW_DCBITERATIONS;Počet průchodů DCB +TP_RAW_DMETHOD;Metoda +TP_RAW_FALSECOLOR;Počet kroků při potlačování chybných barev +TP_RAW_LABEL;Demozajkování +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;Ořez +TP_RESIZE_FITBOX;Výřez +TP_RESIZE_FULLIMAGE;Celý obrázek +TP_RESIZE_FULLSIZE;Plná velikost obrázku: +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_RED;R +TP_ROTATE_DEGREE;Stupně +TP_ROTATE_LABEL;Otočení +TP_ROTATE_SELECTLINE; Vyznačit rovinu +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_SHTONALW;Tonální rozsah stínů +TP_SHARPENEDGE_AMOUNT;Kvantita +TP_SHARPENEDGE_LABEL;Hrany +TP_SHARPENEDGE_PASSES;Počet průchodů +TP_SHARPENEDGE_THREE;Pouze jas +TP_SHARPENING_AMOUNT;Míra +TP_SHARPENING_EDRADIUS;Poloměr +TP_SHARPENING_EDTOLERANCE;Zachování okrajů +TP_SHARPENING_HALOCONTROL;Omezení haló artefatů +TP_SHARPENING_HCAMOUNT;Míra +TP_SHARPENING_LABEL;Doostření +TP_SHARPENING_METHOD;Metoda +TP_SHARPENING_ONLYEDGES;Doostřit pouze okraje +TP_SHARPENING_RADIUS;Poloměr +TP_SHARPENING_RLD;RL Dekonvoluce +TP_SHARPENING_RLD_AMOUNT;Míra +TP_SHARPENING_RLD_DAMPING;Útlum +TP_SHARPENING_RLD_ITERATIONS;Počet průchodů +TP_SHARPENING_THRESHOLD;Práh +TP_SHARPENING_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_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_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_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 +ZOOMBAR_DETAIL;Detaily +ZOOMBAR_HUGE;Veliký +ZOOMBAR_LARGE;Větší +ZOOMBAR_NORMAL;Normální +ZOOMBAR_PREVIEW;Náhled +ZOOMBAR_SCALE;Měřítko +ZOOMBAR_SMALL;Malý +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;Otevřít (nové) okno detailu +ZOOMPANEL_ZOOM100;Zvětšit na 100% 1 +ZOOMPANEL_ZOOMFITSCREEN;Přizpůsobit obrazovce F +ZOOMPANEL_ZOOMIN;Přiblížit + +ZOOMPANEL_ZOOMOUT;Oddálit - + +#00 Czech +#01 20.1.2008: translated by absolution +#02 21.2.2008: updated by mkyral (typos and some missing strings) +#03 24.4.2008: updated by mkyral (for version 2.4m1) +#04 28.10.2008: updated by mkyral (for version 2.4 beta1) +#05 25.11.2010: updated by mkyral (for version 3.0) +#06 06.03.2011: updated by mkyral (default branch) +#07 20.03.2011: updated by mkyral (default branch) +#08 01.05.2011: updated by mkyral +#09 18.05.2011: updated by mkyral +#10 04.06.2011: updated by mkyral +#11 12.06.2011: updated by mkyral +#12 16.06.2011: updated by mkyral +#13 03.07.2011: updated by mkyral +#14 08.07.2011: updated by mkyral +#15 04.09.2011: updated by mkyral +#16 06.09.2011: updated by mkyral +#17 12.11.2011: updated by mkyral +#18 29.12.2011: updated by mkyral +#19 22.02.2012: updated by mkyral +#20 28.04.2012: updated by mkyral + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!GENERAL_WARNING;Warning +!HISTOGRAM_TOOLTIP_FULL;Toggle full or scaled histogram +!HISTORY_MSG_167;B&W Toning +!HISTORY_MSG_168;'Cc' curve +!HISTORY_MSG_169;'Ch' curve +!HISTORY_MSG_170;Vibrance - Curve +!MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 8 +!MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 0 +!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. +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing Profile Saved +!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\nthe 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_CROP_GTFRAME;Frame +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid Color Shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space\nand apply Munsell correction +!TP_LABCURVE_BWTONING;B&W Toning +!TP_LABCURVE_BWTONING_TIP;With B&W Toning option enabled, the Lab Chromaticity, Cc and Ch curves are not in effect.\nToning can be achieved using the a and b curves +!TP_LABCURVE_CHROMATICITY;Chromaticity +!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 the Chromaticity +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to the Hue +!TP_LABCURVE_RSTPROTECTION;Red and Skin Tones Protection +!TP_LENSPROFILE_FILEDLGFILTERLCP;Lens correction files +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;Use CA correction +!TP_LENSPROFILE_USEDIST;Use distortion correction +!TP_LENSPROFILE_USEVIGN;Use vignette correction +!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 the Hue +!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 diff --git a/rtdata/languages/Dansk b/rtdata/languages/Dansk new file mode 100644 index 000000000..5e1572f7a --- /dev/null +++ b/rtdata/languages/Dansk @@ -0,0 +1,1209 @@ +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_DIALOGLABEL;Exif Filter +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_ARRANGEMENTHINT;Skifte mellem lodret og vandret tilpasning af miniaturer +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_EXIFFILTERAPPLYHINT;Slå exif filter til eller fra i filbrowseren +FILEBROWSER_EXIFFILTERAPPLY;Anvend +FILEBROWSER_EXIFFILTERLABEL;Exif filter +FILEBROWSER_EXIFFILTERSETTINGSHINT;Skift indstillinger på exif filteret +FILEBROWSER_EXIFFILTERSETTINGS;Indstillinger +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_POPUPRANK1;Vurdering 1 +FILEBROWSER_POPUPRANK2;Vurdering 2 +FILEBROWSER_POPUPRANK3;Vurdering 3 +FILEBROWSER_POPUPRANK4;Vurdering 4 +FILEBROWSER_POPUPRANK5;Vurdering 5 +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_PROCESSINGSETTINGSHINT;Vælg filformat og destinationsmappe +FILEBROWSER_PROCESSINGSETTINGS;Indstillinger +FILEBROWSER_RENAMEDLGLABEL;Omdøb fil +FILEBROWSER_RENAMEDLGMSG;Omdøb filen "%1" til: +FILEBROWSER_SHOWDIRHINT;Vis alle billeder i mappen +FILEBROWSER_SHOWQUEUEHINT;Vis indhold i opgavekøen +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_LOAD;Indlæs +GENERAL_NA;Ikke muligt +GENERAL_NO;Nej +GENERAL_OK;OK +GENERAL_PORTRAIT;Højformat +GENERAL_SAVE;Gem +GENERAL_YES;Ja +HISTOGRAM_LABEL;Histogram +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_NEWSNAPSHOTAS;Som... +HISTORY_NEWSNAPSHOT;Tilføj... +HISTORY_NEWSSDIALOGLABEL;Mærke på snapshot: +HISTORY_NEWSSDIALOGTITLE;Tilføj nyt snapshot +HISTORY_SETTO;Sæt til +HISTORY_SNAPSHOTS;Snapshots +HISTORY_SNAPSHOT;Snapshot +ICMPANEL_FILEDLGFILTERANY;Alle filer +ICMPANEL_FILEDLGFILTERICM;ICC Profil-filer +ICMPANEL_GAMMABEFOREINPUT;Profil anvender Gamma +ICMPANEL_INPUTCAMERA;Kamerastandard +ICMPANEL_INPUTCUSTOM;Brugervalgt +ICMPANEL_INPUTDLGLABEL;Vælg Input ICC-profil... +ICMPANEL_INPUTEMBEDDED;Brug indlejrede, hvis mulligt +ICMPANEL_INPUTPROFILE;Input-profil +ICMPANEL_NOICM;No ICM: sRGB output +ICMPANEL_OUTPUTDLGLABEL;Vælg output ICC-profil... +ICMPANEL_OUTPUTPROFILE;Output-profil +ICMPANEL_SAVEREFERENCE;Gem referencebillede til profilering +ICMPANEL_WORKINGPROFILE;Nuværende profil +IMAGEAREA_DETAILVIEW;Se detaljer +IPTCPANEL_AUTHORHINT;Navn på skaberen af projektet, fx forfatter, fotograf eller grafisk kunstner (byline). +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_EXIT;Exit +MAIN_BUTTON_PREFERENCES;Indstillinger +MAIN_BUTTON_QUEUE;Put to queue +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_EXITJOBSINQUEUEINFO;Ubearbejdede billeder i køen vil blive mistet, når du lukker. +MAIN_MSG_EXITJOBSINQUEUEQUEST;er du sikker på, at du vil lukke? Der er ubearbejdede billeder, som venter i køen. +MAIN_MSG_JOBSINQUEUE;Opgave(r) i køen +MAIN_MSG_QOVERWRITE;Vil du overskrive? +MAIN_TAB_BASIC;Grundlæggende +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_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;Justér +MAIN_TOOLTIP_HIDEFP;Vis/skjul panelet i bunden (stifinder og filbrowser, genvejstast: F) +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_PREFERENCES;Vælg indstillinger +MAIN_TOOLTIP_QINFO;Udvalgte oplysninger om billedet +MAIN_TOOLTIP_SAVEAS;Gem billedet i en valgfri mappe +MAIN_TOOLTIP_SAVE;Gem billedet i standardmappen +PARTIALPASTE_BASICGROUP;Grundlæggende indstillinger +PARTIALPASTE_CACORRECTION;Kromatisk aberration +PARTIALPASTE_COARSETRANS;Drej/vend 90 grader +PARTIALPASTE_COLORBOOST;Forstærk farver +PARTIALPASTE_COLORDENOISE;Fjern farvestøj +PARTIALPASTE_COLORGROUP;Farverelaterede indstillinger +PARTIALPASTE_COLORMIXER;Farveblander +PARTIALPASTE_COLORSHIFT;Farveskift +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_HLRECOVERY;Red højlys +PARTIALPASTE_ICMSETTINGS;ICM-indstillinger +PARTIALPASTE_IPTCINFO;IPTC-info +PARTIALPASTE_LENSGROUP;Objektivrelaterede indstillinger +PARTIALPASTE_LUMACURVE;Kurve +PARTIALPASTE_LUMADENOISE;Fjern lysstøj +PARTIALPASTE_LUMINANCEGROUP;Lysrelaterede indstillinger +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_CACHESTRAT1;Foretræk hastighed frem for lavt hukommelsesforbrug +PREFERENCES_CACHESTRAT2;Foretræk lavt hukommelsesforbrug frem for hastighed +PREFERENCES_CACHESTRAT;Cache-strategi +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_DEMOSAICINGALGO;Algoritme til rekonstruktion +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_HINT;Hentydning +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_LIVETHUMBNAILS;Opdaterede miniaturer (langsommere) +PREFERENCES_MONITORICC;Skærmprofil +PREFERENCES_OUTDIRFOLDERHINT;Læg det gemte billede i den valgte mappe +PREFERENCES_OUTDIRFOLDER;Gem i mappe +PREFERENCES_OUTDIRHINT;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_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_SELECTICCDIRDLG;Vælg mappe med ICC-profiler... +PREFERENCES_SELECTLANG;Vælg sprog +PREFERENCES_SELECTMONITORPROFDLG;Vælg skærmens ICC-profil... +PREFERENCES_SELECTTHEME;Vælg tema +PREFERENCES_SHOWBASICEXIF;Vis grundlæggende exif-data +PREFERENCES_SHOWDATETIME;Vis dato og tid +PREFERENCES_SHOWONLYRAW;Vis kun RAW-filer +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 +PREFERENCES_TAB_OUTPUT;Output-indstillinger +PREFERENCES_THUMBSIZE;Størrelse på miniaturer +PROFILEPANEL_FILEDLGFILTERANY;Alle filer +PROFILEPANEL_FILEDLGFILTERPP;Efterbehandlingsprofiler +PROFILEPANEL_LABEL;Efterbehandlingsprofiler +PROFILEPANEL_LOADDLGLABEL;Indlæs efterbehandlingsparametre... +PROFILEPANEL_PCUSTOM;Brugervalgt +PROFILEPANEL_PFILE;Fra fil +PROFILEPANEL_PLASTPHOTO;Seneste foto +PROFILEPANEL_PLASTSAVED;Senest gemte +PROFILEPANEL_PROFILE;Profil +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_DECODING;Afkoder RAW-fil... +PROGRESSBAR_DEMOSAICING;Analyserer... +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_FOCALLENGTH;Brændvidde +QINFO_ISO;ISO +QINFO_LENS;Objektiv +QINFO_NOEXIF;Exif-data ikke tilgængelig. +SAVEDLG_FILEFORMAT;Filformat +SAVEDLG_JPEGQUAL;JPEG-kvalitet +SAVEDLG_JPGFILTER;JPEG-filer +SAVEDLG_PNGCOMPR;PNG-komprimering +SAVEDLG_PNGFILTER;PNG-filer +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_OUTPUTDLGLABEL;Vælg output ICC-profil... +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_LUMADENOISE_EDGETOLERANCE;Kanttolerance +TP_LUMADENOISE_LABEL;Lysstøj +TP_LUMADENOISE_RADIUS;Radius +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_FULLSIZE;Fuld billedstørrelse: +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 +ZOOMBAR_DETAIL;Detalje +ZOOMBAR_HUGE;Kæmpe +ZOOMBAR_LARGE;Stor +ZOOMBAR_NORMAL;Normal +ZOOMBAR_PREVIEW;Forhåndsvisning +ZOOMBAR_SCALE;Skalér +ZOOMBAR_SMALL;Lille + +#00 Danish +#01 Translated by krengbo +#02 2009-06-27 +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 +!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_SHARPENEDGE;Bypass Edge Sharpening +!EXPORT_BYPASS_SHARPENING;Bypass Sharpening +!EXPORT_BYPASS_SHARPENMICRO;Bypass Microcontrast +!EXPORT_BYPASS_SH_HQ;Bypass Shadow/Highlights (High Quality) +!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 the path text box.\nEnter / Ctrl-Enter (in the File Browser) to browse there;\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_CURRENT_NAME;Current name: +!FILEBROWSER_DARKFRAME;Dark frame +!FILEBROWSER_DELETEDLGMSGINCLPROC;Are you sure you want to delete the selected %1 files including a queue-processed version? +!FILEBROWSER_EXEC_CPB;Custom Profile Builder +!FILEBROWSER_EXTPROGMENU;Open with +!FILEBROWSER_FLATFIELD;Flat Field +!FILEBROWSER_MOVETODARKFDIR;Move to dark frames directory +!FILEBROWSER_MOVETOFLATFIELDDIR;Move to flat fields directory +!FILEBROWSER_NEW_NAME;New name: +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!FILEBROWSER_POPUPCOLORLABEL0;Label: None +!FILEBROWSER_POPUPCOLORLABEL1;Label: Red +!FILEBROWSER_POPUPCOLORLABEL2;Label: Yellow +!FILEBROWSER_POPUPCOLORLABEL3;Label: Green +!FILEBROWSER_POPUPCOLORLABEL4;Label: Blue +!FILEBROWSER_POPUPCOLORLABEL5;Label: Purple +!FILEBROWSER_POPUPCOLORLABEL;Color label +!FILEBROWSER_POPUPCOPYTO;Copy to... +!FILEBROWSER_POPUPFILEOPERATIONS;File Operations +!FILEBROWSER_POPUPMOVETO;Move to... +!FILEBROWSER_POPUPPROCESSFAST;Put to Queue (Fast export) +!FILEBROWSER_POPUPPROFILEOPERATIONS;Processing Profile Operations +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_POPUPREMOVESUBMENU;Remove +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!FILEBROWSER_QUERYHINT;Type a partial filename to search for.\nCtrl-F to focus the Find text box (in the File Browser).\nEnter to commence search. +!FILEBROWSER_QUERYLABEL; Find: +!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 +!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-` +!FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +!FILEBROWSER_USETEMPLATE;Use template: +!GENERAL_AFTER;After +!GENERAL_BEFORE;Before +!GENERAL_FILE;File +!GENERAL_HIGH_QUALITY;High Quality +!GENERAL_NONE;None +!GENERAL_UNCHANGED;(Unchanged) +!GENERAL_WARNING;Warning +!HISTOGRAM_BUTTON_BAR;RGB +!HISTOGRAM_BUTTON_B;B +!HISTOGRAM_BUTTON_G;G +!HISTOGRAM_BUTTON_L;L +!HISTOGRAM_BUTTON_RAW;Raw +!HISTOGRAM_BUTTON_R;R +!HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar\nClick right mouse button on image preview to freeze/unfreeze +!HISTOGRAM_TOOLTIP_FULL;Toggle full or scaled histogram +!HISTOGRAM_TOOLTIP_RAW;Show/Hide raw histogram +!HISTORY_MSG_82;Profile Changed +!HISTORY_MSG_83;High Quality Shadows/Highlights +!HISTORY_MSG_84;Perspective Correction +!HISTORY_MSG_85;Lens Correction Profile +!HISTORY_MSG_86;Wavelet Equalizer +!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 +!HISTORY_MSG_92;NR - Gamma +!HISTORY_MSG_93;Contrast by Detail Levels Value +!HISTORY_MSG_94;Contrast by Detail Levels +!HISTORY_MSG_95;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;RGB Saturation +!HISTORY_MSG_101;HSV EQ -- Hue +!HISTORY_MSG_102;HSV EQ -- Saturation +!HISTORY_MSG_103;HSV EQ -- Value +!HISTORY_MSG_104;HSV Equalizer +!HISTORY_MSG_105;Defringing +!HISTORY_MSG_106;Defringing Radius +!HISTORY_MSG_107;Defringing Threshold +!HISTORY_MSG_108;Highlight Compr. Threshold +!HISTORY_MSG_109;Resize Bounding Box +!HISTORY_MSG_110;Resizing applies o +!HISTORY_MSG_111;Avoid Color Shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;Red and Skin Tones Protection +!HISTORY_MSG_114;DCB Iterations +!HISTORY_MSG_115;False Color Iterations +!HISTORY_MSG_116;Enhanced DCB +!HISTORY_MSG_117;Red CA Correction +!HISTORY_MSG_118;Blue CA Correction +!HISTORY_MSG_119;Line Denoise +!HISTORY_MSG_120;Green Equil. Threshold +!HISTORY_MSG_121;Auto CA +!HISTORY_MSG_122;Auto Dark Frame +!HISTORY_MSG_123;Dark Frame File +!HISTORY_MSG_124;Linear Exp. Correction +!HISTORY_MSG_125;Exp. Correction Preserving HL +!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;Gamma +!HISTORY_MSG_134;Gamma Position +!HISTORY_MSG_135;Gamma Free +!HISTORY_MSG_136;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 Green Together +!HISTORY_MSG_142;Edges Sharpening - Iterations +!HISTORY_MSG_143;Edges Sharpening - Quantity +!HISTORY_MSG_144;Microcontrast - Quantity +!HISTORY_MSG_145;Microcontrast - Uniformity +!HISTORY_MSG_146;Edges Sharpening +!HISTORY_MSG_147;Edges Sharpening - 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;Vibrance - Pastel tones +!HISTORY_MSG_153;Vibrance - Saturated tones +!HISTORY_MSG_154;Vibrance - Protect skin tones +!HISTORY_MSG_155;Vibrance - Avoid color drift +!HISTORY_MSG_156;Vibrance - Link pastel and saturated tones +!HISTORY_MSG_157;Vibrance - Pastel/Saturated threshold +!HISTORY_MSG_158;Strength +!HISTORY_MSG_159;Edge Stopping +!HISTORY_MSG_160;Scale +!HISTORY_MSG_161;Reweighting Iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_163;RGB Curves - R +!HISTORY_MSG_164;RGB Curves - G +!HISTORY_MSG_165;RGB Curves - B +!HISTORY_MSG_166;Neutral Levels +!HISTORY_MSG_167;B&W Toning +!HISTORY_MSG_168;'Cc' curve +!HISTORY_MSG_169;'Ch' curve +!HISTORY_MSG_170;Vibrance - Curve +!MAIN_BUTTON_FULLSCREEN;Fullscreen +!MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Put current image to processing queue.\nShortcut: Ctrl+Q +!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_ERRORDURINGIMAGESAVING;Error during image saving +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue processed first. +!MAIN_MSG_NAVIGATOR;Navigator +!MAIN_MSG_PLACES;Places +!MAIN_TAB_COLOR_TOOLTIP;Shortcut: Alt-C +!MAIN_TAB_DETAIL_TOOLTIP;Shortcut: Alt-D +!MAIN_TAB_EXPORT; 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_TOGGLE_BEFORE_AFTER;B|A +!MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 8 +!MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 0 +!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_CHANNELMIXER;Channel mixer +!PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto fill +!PARTIALPASTE_DARKFRAMEAUTOSELECT;Dark Frame Auto Select +!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;FF Auto Select +!PARTIALPASTE_FLATFIELDBLURRADIUS;FF Blur Radius +!PARTIALPASTE_FLATFIELDBLURTYPE;FF Blur Type +!PARTIALPASTE_FLATFIELDFILE;Flat field (FF) File +!PARTIALPASTE_HLRECONSTRUCTION;Highlight reconstruction +!PARTIALPASTE_HLRECOVERYAMOUNT;Highlight recovery amount +!PARTIALPASTE_HLRECOVERYTHRESHOLD;Highlight recovery threshold +!PARTIALPASTE_HSVEQUALIZER;HSV Equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!PARTIALPASTE_LABCURVE;Lab adjustments +!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 Level +!PARTIALPASTE_RAWEXPOS_LINEAR;Raw white point linear corr. factor +!PARTIALPASTE_RAWEXPOS_PRESER;Raw white point HL preserving corr. (EV) +!PARTIALPASTE_RAWGROUP;Raw settings +!PARTIALPASTE_RAW_ALLENHANCE;Apply post demosaic artifact/noise reduction +!PARTIALPASTE_RAW_DCBENHANCE;Apply DCB enhancement step +!PARTIALPASTE_RAW_DCBITERATIONS;Number of DCB iterations +!PARTIALPASTE_RAW_DMETHOD;Demosaic Method +!PARTIALPASTE_RAW_FALSECOLOR;Demosaic False color suppression steps +!PARTIALPASTE_RGBCURVES;RGB curves +!PARTIALPASTE_SHARPENEDGE;Edges +!PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_VIBRANCE;Vibrance +!PARTIALPASTE_WAVELETEQUALIZER;Wavelet equalizer +!PREFERENCES_ADD;ADD +!PREFERENCES_AUTOMONPROFILE;Automatically use operating system's main monitor color profile +!PREFERENCES_BATCH_PROCESSING;Batch Processing +!PREFERENCES_BEHAVIOR;Behavior +!PREFERENCES_CUSTPROFBUILDHINT;Executable (or script) file called when a new initial processing profile should be generated for an image.\nReceives command line parameters to allow a rules-based processing profile generation:\n[raw/JPG path] [default processing profile path] [f-number] [exposure in secs] [focal length in mm] [ISO] [lens] [camera] +!PREFERENCES_CUSTPROFBUILDPATH;Executable path +!PREFERENCES_CUSTPROFBUILD;Custom Processing Profile Builder +!PREFERENCES_CUTOVERLAYBRUSH;Crop mask color/transparency +!PREFERENCES_DARKFRAMEFOUND;Found +!PREFERENCES_DARKFRAMESHOTS;shots +!PREFERENCES_DARKFRAMETEMPLATES;templates +!PREFERENCES_DARKFRAME;Dark Frame +!PREFERENCES_DATEFORMATFRAME;Date Format +!PREFERENCES_DIRDARKFRAMES;Dark frames directory +!PREFERENCES_EDITORLAYOUT;Editor Layout +!PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar (de-select for low res display) +!PREFERENCES_FLATFIELDFOUND;Found +!PREFERENCES_FLATFIELDSDIR;Flat Fields directory +!PREFERENCES_FLATFIELDSHOTS;shots +!PREFERENCES_FLATFIELDTEMPLATES;templates +!PREFERENCES_FLATFIELD;Flat Field +!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_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). On Windows use "SystemDefault", "SystemAsterisk" etc. for system sounds. +!PREFERENCES_SND_LNGEDITPROCDONE;Editor processing done +!PREFERENCES_SND_TRESHOLDSECS;after secs +!PREFERENCES_SQUAREDETAILWINDOW;Square detail window (faster) +!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_USESYSTEMTHEME; Use system theme +!PREFERENCES_WORKFLOW;Layout +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_SAVEPPASTE;Parameters to save +!PROGRESSBAR_BADPIXELS;Bad pixels... +!PROGRESSBAR_CACORRECTION;CA correction... +!PROGRESSBAR_DARKFRAME;Darkframe... +!PROGRESSBAR_GREENEQUIL;Green equilibrate... +!PROGRESSBAR_LINEDENOISE;Line Denoise... +!PROGRESSBAR_LOADINGTHUMBS;Loading thumbnails... +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing Profile Saved +!PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists +!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\nthe 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_CHROMATABERR_LABEL;Chromatic Aberration +!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_DETAIL_AMOUNT;Amount +!TP_DIRPYRDENOISE_CHROMA;Chrominance +!TP_DIRPYRDENOISE_GAMMA;Gamma +!TP_DIRPYRDENOISE_LABEL;Noise reduction +!TP_DIRPYRDENOISE_LUMA;Luminance +!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_EQUALIZER_CONTRAST_MINUS;Contrast- +!TP_EQUALIZER_CONTRAST_PLUS;Contrast+ +!TP_EQUALIZER_FINEST;finest +!TP_EQUALIZER_LABEL;Wavelet equalizer +!TP_EQUALIZER_LARGEST;coarsest +!TP_EQUALIZER_NEUTRAL;Neutral +!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 +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in auto levels operation +!TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Highlight recovery threshold +!TP_EXPOSURE_SATURATION;Saturation +!TP_EXPO_AFTER; After interpolation (before RGB conversion) +!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_HLREC_BLEND;Blend +!TP_HSVEQUALIZER_CHANNEL;HSV Channel +!TP_HSVEQUALIZER_HUE;H +!TP_HSVEQUALIZER_LABEL;HSV Equalizer +!TP_HSVEQUALIZER_NEUTRAL;Neutral +!TP_HSVEQUALIZER_SAT;S +!TP_HSVEQUALIZER_VAL;V +!TP_ICM_BLENDCMSMATRIX;Blend highlights with matrix +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover blown highlights when using LUT based ICC profiles +!TP_ICM_INPUTCAMERAICC;Auto-matched camera-specific color profile +!TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profile. These profiles are more precise than simpler matrix ones. Available for some 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_PREFERREDPROFILE;Preferred DCP profile +!TP_ICM_PREFERREDPROFILE_1;Daylight +!TP_ICM_PREFERREDPROFILE_2;Tungsten +!TP_ICM_PREFERREDPROFILE_3;Fluorescent +!TP_ICM_PREFERREDPROFILE_4;Flash +!TP_IMPULSEDENOISE_LABEL;Impulse Noise Reduction +!TP_IMPULSEDENOISE_THRESH;Impulse NR Threshold +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid Color Shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space\nand apply Munsell correction +!TP_LABCURVE_BRIGHTNESS;Brightness +!TP_LABCURVE_BWTONING;B&W Toning +!TP_LABCURVE_BWTONING_TIP;With B&W Toning option enabled, the Lab Chromaticity, Cc and Ch curves are not in effect.\nToning can be achieved using the a and b curves +!TP_LABCURVE_CHROMATICITY;Chromaticity +!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 the Chromaticity +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to the Hue +!TP_LABCURVE_LABEL;Lab Adjustments +!TP_LABCURVE_RSTPROTECTION;Red and Skin Tones Protection +!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;Use CA correction +!TP_LENSPROFILE_USEDIST;Use distortion correction +!TP_LENSPROFILE_USEVIGN;Use vignette correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset exposure controls to neutral values +!TP_PERSPECTIVE_HORIZONTAL;Horizontal +!TP_PERSPECTIVE_LABEL;Perspective +!TP_PERSPECTIVE_VERTICAL;Vertical +!TP_PREPROCESS_GREENEQUIL;Green equilibration +!TP_PREPROCESS_HOTDEADPIXFILT;Apply hot/dead pixel filter +!TP_PREPROCESS_HOTDEADPIXTHRESH;Hot/dead pixel detection threshold +!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 (leader) +!TP_RAWEXPOS_LINEAR;White Point: Linear corr. factor +!TP_RAWEXPOS_PRESER;White Point: HL preserving corr.(EV) +!TP_RAWEXPOS_TWOGREEN;Two greens together +!TP_RAW_ALLENHANCE;Apply post demosaic artifact/noise reduction +!TP_RAW_DCBENHANCE;Apply DCB enhancement step +!TP_RAW_DCBITERATIONS;Number of DCB iterations +!TP_RAW_LABEL;Demosaicing +!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_RED;R +!TP_SHARPENEDGE_AMOUNT;Quantity +!TP_SHARPENEDGE_LABEL;Edges +!TP_SHARPENEDGE_PASSES;Iterations +!TP_SHARPENEDGE_THREE;Luminance only +!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 the Hue +!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_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 +!ZOOMPANEL_100;(100%) +!ZOOMPANEL_NEWCROPWINDOW;Open (new) detail window +!ZOOMPANEL_ZOOM100;Zoom to 100% 1 +!ZOOMPANEL_ZOOMFITSCREEN;Fit to screen F +!ZOOMPANEL_ZOOMIN;Zoom In + +!ZOOMPANEL_ZOOMOUT;Zoom Out - diff --git a/rtdata/languages/Deutsch b/rtdata/languages/Deutsch new file mode 100644 index 000000000..e78d51da5 --- /dev/null +++ b/rtdata/languages/Deutsch @@ -0,0 +1,1216 @@ +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_DIALOGLABEL;Exif Filter +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 zu den ursprünglichen Werten zurücksetzen +EXIFPANEL_RESETALL;Alle zurücksetzen +EXIFPANEL_RESETHINT;Gewählte Attribute zu den ursprünglichen Werten 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_ARRANGEMENTHINT;Zwischen vertikaler und horizontaler Ausrichtung der Voransichten wechseln +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_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_EXIFFILTERAPPLYHINT;Exif Filter im Datei-Browser ein-/ausschalten +FILEBROWSER_EXIFFILTERAPPLY;Anwenden +FILEBROWSER_EXIFFILTERLABEL;Exif Filter +FILEBROWSER_EXIFFILTERSETTINGSHINT;Einstellungen des Exif Filters ändern +FILEBROWSER_EXIFFILTERSETTINGS;Einstellungen +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_POPUPCOLORLABEL0;Markierung: keine +FILEBROWSER_POPUPCOLORLABEL1;Markierung: Rot +FILEBROWSER_POPUPCOLORLABEL2;Markierung: Gelb +FILEBROWSER_POPUPCOLORLABEL3;Markierung: Grün +FILEBROWSER_POPUPCOLORLABEL4;Markierung: Blau +FILEBROWSER_POPUPCOLORLABEL5;Markierung: Violett +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_POPUPRANK1;Bewertung: 1 * +FILEBROWSER_POPUPRANK2;Bewertung: 2 ** +FILEBROWSER_POPUPRANK3;Bewertung: 3 *** +FILEBROWSER_POPUPRANK4;Bewertung: 4 **** +FILEBROWSER_POPUPRANK5;Bewertung: 5 ***** +FILEBROWSER_POPUPRANK;Bewertung +FILEBROWSER_POPUPREMOVEINCLPROC;Löschen (auch Resultate der Stapelverarbeitung) +FILEBROWSER_POPUPREMOVESUBMENU;Löschen +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_PROCESSINGSETTINGSHINT;Einstellen von Ausgabeformat und Ausgabeverzeichnis +FILEBROWSER_PROCESSINGSETTINGS;Einstellungen +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_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_SHOWQUEUEHINT;Inhalt der Warteschlange zeigen +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+` +FILEBROWSER_SHOWUNRANKHINT;Nur unbewertete Bilder anzeigen ` +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_USETEMPLATE;Vorlage verwenden: +FILEBROWSER_ZOOMINHINT;Voransichten vergrößern + +FILEBROWSER_ZOOMOUTHINT;Voransichten verkleinern - +GENERAL_ABOUT;Über +GENERAL_AFTER;Nachher +GENERAL_BEFORE;Vorher +GENERAL_CANCEL;Abbruch +GENERAL_DISABLED;Deaktiviert +GENERAL_DISABLE;Deaktivieren +GENERAL_ENABLED;Aktiv +GENERAL_ENABLE;Aktivieren +GENERAL_FILE;Datei +GENERAL_HIGH_QUALITY;Hohe Qualität +GENERAL_LANDSCAPE;Quer +GENERAL_LOAD;Laden +GENERAL_NA;n/a +GENERAL_NONE;Keins +GENERAL_NO;Nein +GENERAL_OK;OK +GENERAL_PORTRAIT;Hoch +GENERAL_SAVE;Speichern +GENERAL_UNCHANGED;(Unverändert) +GENERAL_YES;Ja +HISTOGRAM_BUTTON_BAR;RGB +HISTOGRAM_BUTTON_B;B +HISTOGRAM_BUTTON_G;G +HISTOGRAM_BUTTON_L;L +HISTOGRAM_BUTTON_RAW;RAW +HISTOGRAM_BUTTON_R;R +HISTOGRAM_LABEL;Histogramm +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_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;Drehung +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_NEWSNAPSHOTAS;als... +HISTORY_NEWSNAPSHOT;Hinzuf. +HISTORY_NEWSSDIALOGLABEL;Name der Variante: +HISTORY_NEWSSDIALOGTITLE;Variante hinzufügen +HISTORY_SETTO;Setzen auf +HISTORY_SNAPSHOTS;Varianten +HISTORY_SNAPSHOT;Variante +ICMPANEL_FILEDLGFILTERANY;Alle Dateien +ICMPANEL_FILEDLGFILTERICM;ICC-Profildatei +ICMPANEL_GAMMABEFOREINPUT;Profil enthält Gammaanpassung +ICMPANEL_INPUTCAMERA;Kamera-Standard +ICMPANEL_INPUTCUSTOM;Benutzerdefiniert +ICMPANEL_INPUTDLGLABEL;Wähle Eingabe-ICC-Profil... +ICMPANEL_INPUTEMBEDDED;Eingebettetes verwenden, falls möglich +ICMPANEL_INPUTPROFILE;Eingabeprofil +ICMPANEL_NOICM;Kein ICM: sRGB-Ausgabe +ICMPANEL_OUTPUTDLGLABEL;Wähle Ausgabe-ICC-Profil... +ICMPANEL_OUTPUTPROFILE;Ausgabeprofil +ICMPANEL_SAVEREFERENCE;Referenzbild für Profil speichern +ICMPANEL_WORKINGPROFILE;Arbeitsfarbraum +IMAGEAREA_DETAILVIEW;Detailansicht +IPTCPANEL_AUTHORHINT;Name des Autors, z.B. Name des Fotografen oder des Künstlers (By-line) +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_EXIT;Verlassen +MAIN_BUTTON_FULLSCREEN;Vollbild F11 +MAIN_BUTTON_PREFERENCES;Einstellungen +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Bild in Warteschlange einreihen Strg+Q +MAIN_BUTTON_QUEUE;In die Warteschlange +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_ERRORDURINGIMAGESAVING;Fehler beim Speichern des Bildes +MAIN_MSG_EXITJOBSINQUEUEINFO;Unverarbeitete Bilder in der Warteschlange gehen beim Verlassen der Anwendung verloren. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Wollen Sie die Anwendung wirklich schließen? Es sind noch unverarbeitete Bilder in der Warteschlange. +MAIN_MSG_IMAGEUNPROCESSED;Für diese Funktion müssen erst alle Bilder stapelverarbeitet sein. +MAIN_MSG_JOBSINQUEUE;Job in Bearbeitung +MAIN_MSG_NAVIGATOR;Navigator +MAIN_MSG_PLACES;Orte +MAIN_MSG_QOVERWRITE;Möchten Sie die Datei überschreiben? +MAIN_TAB_BASIC;Basis +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_ICM;ICM +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_TOGGLE_BEFORE_AFTER;V|N +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_HIDEFP;Unteres Bedienfeld ein-/ausblenden (Verzeichnis- und Datei-Browser) F +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_PREFERENCES;Einstellungen ändern +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_SAVEAS;Bild in anderem Verzeichnis speichern +MAIN_TOOLTIP_SAVE;Bild im Standardverzeichnis speichern +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. +PARTIALPASTE_BASICGROUP;Gruppe Basiseinstellungen +PARTIALPASTE_CACORRECTION;Farbsaum entfernen +PARTIALPASTE_CHANNELMIXER;Kanal-Mixer +PARTIALPASTE_COARSETRANS;Drehen / Spiegeln +PARTIALPASTE_COLORBOOST;Farbverstärkung +PARTIALPASTE_COLORDENOISE;Farb-Rauschfilter +PARTIALPASTE_COLORGROUP;Gruppe Farbeinstellungen +PARTIALPASTE_COLORMIXER;Kanal-Mixer +PARTIALPASTE_COLORSHIFT;Farbverschiebung +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_HLRECONSTRUCTION;Lichter wiederherstellen +PARTIALPASTE_HLRECOVERYAMOUNT;Lichter wiederherstellen\nStärke +PARTIALPASTE_HLRECOVERYTHRESHOLD;Lichter wiederherstellen\nSchwellenwert +PARTIALPASTE_HLRECOVERY;Lichter wiederherstellen +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_LUMADENOISE;Luminanz-Rauschfilter +PARTIALPASTE_LUMINANCEGROUP;Gruppe Luminanzeinstellungen +PARTIALPASTE_METAICMGROUP;Gruppe Metadaten / ICM +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_WAVELETEQUALIZER;Wavelet-Mixer +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_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_CACHESTRAT1;Priorität auf Geschwindigkeit (erhöhter Speicherverbrauch) +PREFERENCES_CACHESTRAT2;Priorität auf minimierten Speicherverbrauch (geringere Geschwindigkeit) +PREFERENCES_CACHESTRAT;Strategie des Zwischenspeichers +PREFERENCES_CACHETHUMBFORM;Format der Voransichten +PREFERENCES_CACHETHUMBHEIGHT;Maximale Höhe der Voransichten +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_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_DEMOSAICINGALGO;Algorithmus zur Entrasterung +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_FORIMAGE;Für Bilddateien +PREFERENCES_FORRAW;Für RAW-Dateien +PREFERENCES_GIMPPATH;GIMP Installationsverzeichnis +PREFERENCES_GTKTHEME;Standard GTK +PREFERENCES_HINT;Erklärungen +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_LIVETHUMBNAILS;Live Voransichten (langsamer) +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_OUTDIRHINT;Erzeugte Dateien gemäß Vorlage benennen und ablegen.\n\nDie folgenden Variablen können verwendet werden:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nDiese Variablen beinhalten bestimmte Teile des Verzeichnispfades, in welchem sich ein Bild befindet.\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 +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_SELECTFONT;Schriftart +PREFERENCES_SELECTICCDIRDLG;Wähle ICC-Profile-Verzeichnis... +PREFERENCES_SELECTLANG;Sprache +PREFERENCES_SELECTMONITORPROFDLG;Wähle ICC-Profil für den Monitor... +PREFERENCES_SELECTTHEME;Oberflächendesign +PREFERENCES_SET;SETZEN +PREFERENCES_SHOWBASICEXIF;Exif-Daten anzeigen +PREFERENCES_SHOWDATETIME;Datum und Uhrzeit anzeigen +PREFERENCES_SHOWEXPOSURECOMPENSATION;Belichtungskorrektur anfügen +PREFERENCES_SHOWONLYRAW;Nur RAW-Dateien anzeigen +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_OUTPUT;Ausgabe +PREFERENCES_TAB_SOUND;Systemklänge +PREFERENCES_THUMBSIZE;Größe der Vorschau +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_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_PLASTPHOTO;Letztes Bild +PROFILEPANEL_PLASTSAVED;Zuletzt gespeichert +PROFILEPANEL_PROFILE;Profil +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_BADPIXELS;Fehlerhafte Pixel... +PROGRESSBAR_CACORRECTION;CA-Korrektur... +PROGRESSBAR_DARKFRAME;Dunkelbild... +PROGRESSBAR_DECODING;Dekodiere RAW... +PROGRESSBAR_DEMOSAICING;Entrasterung... +PROGRESSBAR_GREENEQUIL;Grün-Ausgleich... +PROGRESSBAR_LINEDENOISE;Zeilenrauschfilter... +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_READY;Bereit. +PROGRESSBAR_SAVEJPEG;Speichere JPEG... +PROGRESSBAR_SAVEPNG;Speichere PNG... +PROGRESSBAR_SAVETIFF;Speichere TIFF... +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profil wurde im Browser geändert +QINFO_FOCALLENGTH;Brennweite +QINFO_ISO;ISO +QINFO_LENS;Objektiv +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_PNGFILTER;PNG-Datei +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 +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_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_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_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_CHROMA;Chrominanz +TP_DIRPYRDENOISE_GAMMA;Gamma +TP_DIRPYRDENOISE_LABEL;Rauschminderung +TP_DIRPYRDENOISE_LUMA;Luminanz +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_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_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_WEIGHTEDSTD;Weighted Standard +TP_EXPOSURE_TCMODE_STANDARD;Standard +TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Saturation and Value Blending +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_HLREC_BLEND;Blending +TP_HLREC_CIELAB;CIELab Blending +TP_HLREC_COLOR;Color Propagation +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_NEUTRAL;Neutral +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 /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_OUTPUTDLGLABEL;Wähle Ausgabe-ICC-Profil... +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_BRIGHTNESS;Helligkeit +TP_LABCURVE_CONTRAST;Kontrast +TP_LABCURVE_CURVEEDITOR;Luminanzkurve +TP_LABCURVE_ENABLESATLIMITER;Sättigungsbegrenzung aktivieren +TP_LABCURVE_LABEL;Lab-Anpassungen +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_LUMADENOISE_EDGETOLERANCE;Kantentoleranz +TP_LUMADENOISE_LABEL;Luminanz-Rauschfilter +TP_LUMADENOISE_RADIUS;Radius +TP_NEUTRAL;Neutral +TP_NEUTRAL_TIP;Belichtungseinstellungen auf neutrale Werte zurücksetzen +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_FULLSIZE;Volle Bildgröße: +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_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_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_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_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 +ZOOMBAR_DETAIL;Detail +ZOOMBAR_HUGE;riesig +ZOOMBAR_LARGE;groß +ZOOMBAR_NORMAL;normal +ZOOMBAR_PREVIEW;Voransicht +ZOOMBAR_SCALE;Vergrößerung +ZOOMBAR_SMALL;klein +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;(Weiteres) Detailfenster öffnen +ZOOMPANEL_ZOOM100;Zoom 100% 1 +ZOOMPANEL_ZOOMFITSCREEN;An Bildschirm anpassen F +ZOOMPANEL_ZOOMIN;Hineinzoomen + +ZOOMPANEL_ZOOMOUT;Herauszoomen - + +#00 Deutsch +#01 (keenonkites; Aktualisierte Version für 2.3 beta2) +#02 (phberlin; basiert auf keenonkites' Erstübersetzung) +#03 08.01.2008/15.01.2008/20.02.2008 +#04 19.12.2008: keenonkites, Anpassungen für 2.4beta4 +#05 20.12.2007 +#06 20.9.2008: keenonkites, Anpassungen für 2.4m2 +#07 22.12.2007 +#08 4.4.2008: Anpassungen für 2.4 +#09 Leichte Anpassungen (keenonkites/klonk) +#10 Erweiterung (oduis) +#11 Erweiterung (oduis) +#12 Erweiterung (oduis) +#13 Erweiterung (oduis) +#14 05.12.2010, 3.0 alpha: Erweiterung und Korrekturen (Metex) +#15 Jan'11-Apr'12: Erweiterungen und Korrekturen (MaWe, 29.04.2012) +#16 Erweiterung (oduis) +#17 Erweiterung (oduis) + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!GENERAL_WARNING;Warning +!HISTOGRAM_TOOLTIP_FULL;Toggle full or scaled histogram +!HISTORY_MSG_167;B&W Toning +!HISTORY_MSG_168;'Cc' curve +!HISTORY_MSG_169;'Ch' curve +!HISTORY_MSG_170;Vibrance - Curve +!MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 8 +!MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 0 +!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. +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing Profile Saved +!SAVEDLG_WARNFILENAME;File will be named +!SHCSELECTOR_TOOLTIP;Click right mouse button to reset\nthe 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_CROP_GTFRAME;Frame +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid Color Shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space\nand apply Munsell correction +!TP_LABCURVE_BWTONING;B&W Toning +!TP_LABCURVE_BWTONING_TIP;With B&W Toning option enabled, the Lab Chromaticity, Cc and Ch curves are not in effect.\nToning can be achieved using the a and b curves +!TP_LABCURVE_CHROMATICITY;Chromaticity +!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 the Chromaticity +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to the Hue +!TP_LABCURVE_RSTPROTECTION;Red and Skin Tones Protection +!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 the Hue +!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 diff --git a/rtdata/languages/English (UK) b/rtdata/languages/English (UK) new file mode 100644 index 000000000..6e516f57e --- /dev/null +++ b/rtdata/languages/English (UK) @@ -0,0 +1,1179 @@ +EXPORT_BYPASS_COLORDENOISE;Bypass Colour denoise +EXPORT_BYPASS_RAW_CCSTEPS;Bypass [raw] False Colour Suppression +FILEBROWSER_POPUPCOLORLABEL0;Label: None +FILEBROWSER_POPUPCOLORLABEL1;Label: Red +FILEBROWSER_POPUPCOLORLABEL2;Label: Yellow +FILEBROWSER_POPUPCOLORLABEL3;Label: Green +FILEBROWSER_POPUPCOLORLABEL4;Label: Blue +FILEBROWSER_POPUPCOLORLABEL5;Label: Purple +FILEBROWSER_POPUPCOLORLABEL;Colour label +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_SHOWUNCOLORHINT;Show images without Colour label.\nShortcut: Alt-` +HISTORY_MSG_39;Colour Temperature +HISTORY_MSG_46;Colour Denoising +HISTORY_MSG_49;Edge Sensitive Colour Denoising +HISTORY_MSG_69;Working Colour Space +HISTORY_MSG_70;Output Colour Space +HISTORY_MSG_71;Input Colour Space +HISTORY_MSG_111;Avoid colour shift +HISTORY_MSG_115;False Colour Iterations +HISTORY_MSG_155;Vibrance - Avoid colour shift +ICMPANEL_FILEDLGFILTERICM;Colour profiles +ICMPANEL_GAMMABEFOREINPUT;Colour Profile Applies Gamma +ICMPANEL_INPUTDLGLABEL;Select Input Colour Profile... +ICMPANEL_INPUTPROFILE;Input Colour Profile +ICMPANEL_OUTPUTDLGLABEL;Select Output Colour Profile... +ICMPANEL_OUTPUTPROFILE;Output Colour Profile +ICMPANEL_WORKINGPROFILE;Working Colour Profile +MAIN_TAB_COLOR;Colour +MAIN_TAB_COLOR_TOOLTIP;Shortcut: Alt-C +MAIN_TOOLTIP_BACKCOLOR0;Background colour of the preview: Theme-based\nShortcut: 8 +MAIN_TOOLTIP_BACKCOLOR1;Background colour of the preview: Black\nShortcut: 9 +MAIN_TOOLTIP_BACKCOLOR2;Background colour of the preview: White\nShortcut: 0 +PARTIALPASTE_COLORBOOST;Colour boost +PARTIALPASTE_COLORDENOISE;Colour denoise +PARTIALPASTE_COLORGROUP;Colour Related Settings +PARTIALPASTE_COLORMIXER;Colour mixer +PARTIALPASTE_COLORSHIFT;Colour shift +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_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_SELECTICCDIRDLG;Select Colour Profile Directory... +PREFERENCES_SELECTMONITORPROFDLG;Select Colour Profile of the Display... +PREFERENCES_TAB_COLORMGR;Colour Management +TP_HLREC_COLOR;Colour Propagation +TP_ICM_FILEDLGFILTERICM;Colour profiles +TP_ICM_INPUTCAMERAICC;Auto-matched camera-specific colour profile +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\nand apply Munsell correction +TP_RAW_FALSECOLOR;False Colour Suppression Steps +TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid colour shift +PREFERENCES_BEHAVIOR;Behaviour +!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 +!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_DIALOGLABEL;Exif Filter +!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_SHARPENEDGE;Bypass Edge Sharpening +!EXPORT_BYPASS_SHARPENING;Bypass Sharpening +!EXPORT_BYPASS_SHARPENMICRO;Bypass Microcontrast +!EXPORT_BYPASS_SH_HQ;Bypass Shadow/Highlights (High Quality) +!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_ARRANGEMENTHINT;Change between vertical/horizontal alignment of thumbnails +!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 the path text box.\nEnter / Ctrl-Enter (in the File Browser) to browse there;\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_EXIFFILTERAPPLYHINT;Switch File Browser Exif Filter on/off +!FILEBROWSER_EXIFFILTERAPPLY;Apply +!FILEBROWSER_EXIFFILTERLABEL;Exif Filter +!FILEBROWSER_EXIFFILTERSETTINGSHINT;Change settings of the Exif Filter +!FILEBROWSER_EXIFFILTERSETTINGS;Setup +!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_POPUPRANK1;Rank 1 * +!FILEBROWSER_POPUPRANK2;Rank 2 ** +!FILEBROWSER_POPUPRANK3;Rank 3 *** +!FILEBROWSER_POPUPRANK4;Rank 4 **** +!FILEBROWSER_POPUPRANK5;Rank 5 ***** +!FILEBROWSER_POPUPRANK;Rank +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_POPUPREMOVESUBMENU;Remove +!FILEBROWSER_POPUPREMOVE;Delete +!FILEBROWSER_POPUPRENAME;Rename +!FILEBROWSER_POPUPSELECTALL;Select all +!FILEBROWSER_POPUPTRASH;Move to trash +!FILEBROWSER_POPUPUNRANK;Unrank +!FILEBROWSER_POPUPUNTRASH;Remove from trash +!FILEBROWSER_PROCESSINGSETTINGSHINT;Set the file format and output directory +!FILEBROWSER_PROCESSINGSETTINGS;Settings +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!FILEBROWSER_QUERYHINT;Type a partial filename to search for.\nCtrl-F to focus the Find text box (in the File Browser).\nEnter to commence search. +!FILEBROWSER_QUERYLABEL; Find: +!FILEBROWSER_RENAMEDLGLABEL;Rename file +!FILEBROWSER_RENAMEDLGMSG;Rename file "%1" to: +!FILEBROWSER_SELECTDARKFRAME;Select dark frame... +!FILEBROWSER_SELECTFLATFIELD;Select flat field... +!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 +!FILEBROWSER_SHOWQUEUEHINT;Show content of the processing queue +!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: ` +!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_USETEMPLATE;Use template: +!FILEBROWSER_ZOOMINHINT;Increase thumbnail size.\nShortcut: + +!FILEBROWSER_ZOOMOUTHINT;Decrease thumbnail size.\nShortcut: - +!GENERAL_ABOUT;About +!GENERAL_AFTER;After +!GENERAL_BEFORE;Before +!GENERAL_CANCEL;Cancel +!GENERAL_DISABLED;Disabled +!GENERAL_DISABLE;Disable +!GENERAL_ENABLED;Enabled +!GENERAL_ENABLE;Enable +!GENERAL_FILE;File +!GENERAL_HIGH_QUALITY;High quality +!GENERAL_LANDSCAPE;Landscape +!GENERAL_LOAD;Load +!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 +!GENERAL_YES;Yes +!HISTOGRAM_BUTTON_BAR;RGB +!HISTOGRAM_BUTTON_B;B +!HISTOGRAM_BUTTON_G;G +!HISTOGRAM_BUTTON_L;L +!HISTOGRAM_BUTTON_RAW;Raw +!HISTOGRAM_BUTTON_R;R +!HISTOGRAM_LABEL;Histogram +!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_FULL;Toggle full or scaled 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;Brightness +!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 Exposure +!HISTORY_MSG_13;Exposure Clipping +!HISTORY_MSG_14;Luminance Brightness +!HISTORY_MSG_15;Luminance 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;Sharpening Radius +!HISTORY_MSG_22;Sharpening Amount +!HISTORY_MSG_23;Sharpening Threshold +!HISTORY_MSG_24;Sharpen only edges +!HISTORY_MSG_25;Sharpening Edge Detection Radius +!HISTORY_MSG_26;Sharpening Edge Tolerance +!HISTORY_MSG_27;Sharpening halo control +!HISTORY_MSG_28;Halo Control Amount +!HISTORY_MSG_29;Sharpening Method +!HISTORY_MSG_30;Deconvolution Radius +!HISTORY_MSG_31;Deconvolution Amount +!HISTORY_MSG_32;Deconvolution Damping +!HISTORY_MSG_33;Deconvolution 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_40;White Balance 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_50;Shadow/Highlight +!HISTORY_MSG_51;Highlights +!HISTORY_MSG_52;Shadows +!HISTORY_MSG_53;Highlight Tonal Width +!HISTORY_MSG_54;Shadow Tonal Width +!HISTORY_MSG_55;Local Contrast +!HISTORY_MSG_56;Shadow/Highlight 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;Lens Distortion Correction +!HISTORY_MSG_63;Snapshot Selected +!HISTORY_MSG_64;Crop Photo +!HISTORY_MSG_65;CA correction +!HISTORY_MSG_66;Highlight Recovery +!HISTORY_MSG_67;Highlight Recovery Amount +!HISTORY_MSG_68;Highlight Recovery Method +!HISTORY_MSG_72;Vignetting correction +!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 Enabled +!HISTORY_MSG_82;Profile Changed +!HISTORY_MSG_83;High Quality Shadows/Highlights +!HISTORY_MSG_84;Perspective Correction +!HISTORY_MSG_85;Lens Correction Profile +!HISTORY_MSG_86;Wavelet Equalizer +!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 +!HISTORY_MSG_92;NR - Gamma +!HISTORY_MSG_93;Contrast by Detail Levels Value +!HISTORY_MSG_94;Contrast by Detail Levels +!HISTORY_MSG_95;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;RGB Saturation +!HISTORY_MSG_101;HSV EQ -- Hue +!HISTORY_MSG_102;HSV EQ -- Saturation +!HISTORY_MSG_103;HSV EQ -- Value +!HISTORY_MSG_104;HSV Equalizer +!HISTORY_MSG_105;Defringing +!HISTORY_MSG_106;Defringing Radius +!HISTORY_MSG_107;Defringing 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;Red and Skin Tones Protection +!HISTORY_MSG_114;DCB Iterations +!HISTORY_MSG_116;Enhanced DCB +!HISTORY_MSG_117;Raw Red CA Correction +!HISTORY_MSG_118;Raw Blue CA Correction +!HISTORY_MSG_119;Line Denoise +!HISTORY_MSG_120;Green Equil. Threshold +!HISTORY_MSG_121;Raw Auto CA +!HISTORY_MSG_122;Auto Dark Frame +!HISTORY_MSG_123;Dark Frame File +!HISTORY_MSG_124;Linear Exp. Correction +!HISTORY_MSG_125;Exp. Correction Preserving HL +!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;Gamma +!HISTORY_MSG_134;Gamma Position +!HISTORY_MSG_135;Gamma free +!HISTORY_MSG_136;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 Green Together +!HISTORY_MSG_142;Edges Sharpening - Iterations +!HISTORY_MSG_143;Edges Sharpening - Quantity +!HISTORY_MSG_144;Microcontrast - Quantity +!HISTORY_MSG_145;Microcontrast - Uniformity +!HISTORY_MSG_146;Edges Sharpening +!HISTORY_MSG_147;Edges Sharpening - 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;Vibrance - Pastel tones +!HISTORY_MSG_153;Vibrance - Saturated tones +!HISTORY_MSG_154;Vibrance - Protect skin tones +!HISTORY_MSG_156;Vibrance - Link pastel and saturated tones +!HISTORY_MSG_157;Vibrance - Pastel/Saturated threshold +!HISTORY_MSG_158;Strength +!HISTORY_MSG_159;Edge Stopping +!HISTORY_MSG_160;Scale +!HISTORY_MSG_161;Reweighting Iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_163;RGB Curves - R +!HISTORY_MSG_164;RGB Curves - G +!HISTORY_MSG_165;RGB Curves - B +!HISTORY_MSG_166;Neutral Levels +!HISTORY_MSG_167;B&W toning +!HISTORY_MSG_168;'CC' curve +!HISTORY_MSG_169;'CH' curve +!HISTORY_MSG_170;Vibrance - Curve +!HISTORY_MSG_171;'LC' curve +!HISTORY_MSG_172;Restrict LC to red and skin tones +!HISTORY_MSG_173;NR - Luminance Detail +!HISTORY_NEWSNAPSHOTAS;As... +!HISTORY_NEWSNAPSHOT;Add +!HISTORY_NEWSSDIALOGLABEL;Label of the snapshot: +!HISTORY_NEWSSDIALOGTITLE;Add new snapshot +!HISTORY_SETTO;Set to +!HISTORY_SNAPSHOTS;Snapshots +!HISTORY_SNAPSHOT;Snapshot +!ICMPANEL_FILEDLGFILTERANY;Any files +!ICMPANEL_INPUTCAMERA;Camera Default +!ICMPANEL_INPUTCUSTOM;Custom +!ICMPANEL_INPUTEMBEDDED;Use Embedded, if possible +!ICMPANEL_NOICM;No ICM: sRGB Output +!ICMPANEL_SAVEREFERENCE;Save reference image for profiling +!IMAGEAREA_DETAILVIEW;Detail View +!IPTCPANEL_AUTHORHINT;Name of the creator of the object, e.g. writer, photographer or graphic artist (By-line). +!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_EXIT;Exit +!MAIN_BUTTON_FULLSCREEN;Fullscreen +!MAIN_BUTTON_PREFERENCES;Preferences +!MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Put current image to processing queue.\nShortcut: Ctrl+Q +!MAIN_BUTTON_QUEUE;Put to Queue +!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_ERRORDURINGIMAGESAVING;Error during image saving +!MAIN_MSG_EXITJOBSINQUEUEINFO;Unprocessed images in the queue will be lost on exit. +!MAIN_MSG_EXITJOBSINQUEUEQUEST;Are you sure you want to exit? There are unprocessed images waiting in the queue. +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue processed first. +!MAIN_MSG_JOBSINQUEUE;job(s) in the queue +!MAIN_MSG_NAVIGATOR;Navigator +!MAIN_MSG_PLACES;Places +!MAIN_MSG_QOVERWRITE;Do you want to overwrite it? +!MAIN_TAB_BASIC;Basic +!MAIN_TAB_DETAIL;Detail +!MAIN_TAB_DETAIL_TOOLTIP;Shortcut: Alt-D +!MAIN_TAB_DEVELOP; Develop +!MAIN_TAB_EXIF;Exif +!MAIN_TAB_EXPORT; Export +!MAIN_TAB_EXPOSURE;Exposure +!MAIN_TAB_EXPOSURE_TOOLTIP;Shortcut: Alt-E +!MAIN_TAB_FILTER; Filter +!MAIN_TAB_ICM;ICM +!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_TOGGLE_BEFORE_AFTER;B|A +!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_HIDEFP;Show/Hide the bottom panel (directory and file browser).\nShortcut: F +!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_PREFERENCES;Set preferences +!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_SAVEAS;Save image to a specific folder +!MAIN_TOOLTIP_SAVE;Save image to the default folder +!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;CA correction +!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 select +!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;FF auto select +!PARTIALPASTE_FLATFIELDBLURRADIUS;FF blur radius +!PARTIALPASTE_FLATFIELDBLURTYPE;FF blur type +!PARTIALPASTE_FLATFIELDFILE;Flat field (FF) File +!PARTIALPASTE_HLRECONSTRUCTION;Highlight reconstruction +!PARTIALPASTE_HLRECOVERYAMOUNT;Highlight recovery amount +!PARTIALPASTE_HLRECOVERYTHRESHOLD;Highlight recovery threshold +!PARTIALPASTE_HLRECOVERY;Highlight recovery +!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_LUMADENOISE;Luminance noise reduction +!PARTIALPASTE_LUMINANCEGROUP;Luminance related settings +!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 level +!PARTIALPASTE_RAWEXPOS_LINEAR;White point linear corr. factor +!PARTIALPASTE_RAWEXPOS_PRESER;White point HL preserving corr. (EV) +!PARTIALPASTE_RAWGROUP;Raw Settings +!PARTIALPASTE_RAW_ALLENHANCE;Apply post demosaic artifact/noise reduction +!PARTIALPASTE_RAW_DCBENHANCE;Apply DCB enhancement step +!PARTIALPASTE_RAW_DCBITERATIONS;Number of DCB iterations +!PARTIALPASTE_RAW_DMETHOD;Demosaic method +!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_WAVELETEQUALIZER;Wavelet equalizer +!PARTIALPASTE_WHITEBALANCE;White balance +!PREFERENCES_ADD;Add +!PREFERENCES_APPLNEXTSTARTUP;restart required +!PREFERENCES_BATCH_PROCESSING;Batch Processing +!PREFERENCES_BLINKCLIPPED;Blink clipped areas +!PREFERENCES_CACHECLEARALL;Clear All +!PREFERENCES_CACHECLEARPROFILES;Clear Processing 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_CACHESTRAT1;Prefer Speed to Low Memory Consumption +!PREFERENCES_CACHESTRAT2;Prefer Low Memory Consumption to Speed +!PREFERENCES_CACHESTRAT;Cache Strategy +!PREFERENCES_CACHETHUMBFORM;Cache thumbnail format +!PREFERENCES_CACHETHUMBHEIGHT;Maximal thumbnail height +!PREFERENCES_CLIPPINGIND;Clipping Indication +!PREFERENCES_CUSTPROFBUILDHINT;Executable (or script) file called when a new initial processing profile should be generated for an image.\nReceives command line parameters to allow a rules-based processing profile generation:\n[raw/JPG path] [default processing profile path] [f-number] [exposure in secs] [focal length in mm] [ISO] [lens] [camera] +!PREFERENCES_CUSTPROFBUILDPATH;Executable path +!PREFERENCES_CUSTPROFBUILD;Custom Processing Profile Builder +!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_DEMOSAICINGALGO;Demosaicing Algorithm +!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_FORIMAGE;For non-raw photos +!PREFERENCES_FORRAW;For raw photos +!PREFERENCES_GIMPPATH;GIMP installation directory +!PREFERENCES_GTKTHEME;GTK default +!PREFERENCES_HINT;Hint +!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_LIVETHUMBNAILS;Live Thumbnails (slower) +!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_OUTDIRHINT;You can use the following formatting strings:\n%f, %d1, %d2, ..., %p1, %p2, ..., %r\n\nThese formatting strings refer to the different parts of the photo's pathname or some attributes of the photo.\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\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_OUTDIRTEMPLATEHINT;You can use the following formatting strings:\n%f, %d1, %d2, ..., %p1, %p2, ..., %r\n\nThese formatting strings refer to the different parts of the photo's pathname or some attributes of the photo.\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\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_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_SHOWONLYRAW;Show only raw files +!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). On Windows use "SystemDefault", "SystemAsterisk" 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_OUTPUT;Output Options +!PREFERENCES_TAB_SOUND;Sounds +!PREFERENCES_THUMBSIZE;Thumbnail Size +!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_USESYSTEMTHEME;Use system theme +!PREFERENCES_WORKFLOW;Layout +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_FILEDLGFILTERANY;Any files +!PROFILEPANEL_FILEDLGFILTERPP;Processing profiles +!PROFILEPANEL_LABEL;Processing Profiles +!PROFILEPANEL_LOADDLGLABEL;Load Processing Parameters... +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_PCUSTOM;Custom +!PROFILEPANEL_PFILE;From file +!PROFILEPANEL_PLASTPHOTO;Last Photo +!PROFILEPANEL_PLASTSAVED;Last Saved +!PROFILEPANEL_PROFILE;Profile +!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_BADPIXELS;Bad pixels... +!PROGRESSBAR_CACORRECTION;CA correction... +!PROGRESSBAR_DARKFRAME;Darkframe... +!PROGRESSBAR_DECODING;Decoding raw file... +!PROGRESSBAR_DEMOSAICING;Demosaicing... +!PROGRESSBAR_GREENEQUIL;Green equilibrating... +!PROGRESSBAR_LINEDENOISE;Line denoise... +!PROGRESSBAR_LOADINGTHUMBS;Loading thumbnails... +!PROGRESSBAR_LOADING;Loading image... +!PROGRESSBAR_LOADJPEG;Loading JPEG file... +!PROGRESSBAR_LOADPNG;Loading PNG file... +!PROGRESSBAR_LOADTIFF;Loading TIFF file... +!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... +!PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!QINFO_FOCALLENGTH;Focal length +!QINFO_ISO;ISO +!QINFO_LENS;Lens +!QINFO_NOEXIF;Exif data not available. +!SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists +!SAVEDLG_FILEFORMAT;File format +!SAVEDLG_JPEGQUAL;JPEG Quality +!SAVEDLG_JPGFILTER;JPEG files +!SAVEDLG_PNGCOMPR;PNG Compression +!SAVEDLG_PNGFILTER;PNG files +!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\nthe 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 +!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_CACORRECTION_BLUE;Blue +!TP_CACORRECTION_LABEL;CA 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: [ +!TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotate right.\nShortcut: ] +!TP_COARSETRAF_TOOLTIP_VFLIP;Flip vertically +!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_CHROMA;Chrominance +!TP_DIRPYRDENOISE_GAMMA;Gamma +!TP_DIRPYRDENOISE_LABEL;Noise Reduction (raw images only) +!TP_DIRPYRDENOISE_LDETAIL;Luminance Detail +!TP_DIRPYRDENOISE_LUMA;Luminance +!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 +!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 +!TP_EXPOSURE_BLACKLEVEL;Black +!TP_EXPOSURE_BRIGHTNESS;Brightness +!TP_EXPOSURE_CLIP;Clip +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in auto level's operation +!TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Highlight Recovery Threshold +!TP_EXPOSURE_COMPRHIGHLIGHTS;Highlight Recovery Amount +!TP_EXPOSURE_COMPRSHADOWS;Shadow Recovery +!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_WEIGHTEDSTD;Weighted Standard +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Saturation and Value Blending +!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_HLREC_BLEND;Blend +!TP_HLREC_CIELAB;CIELab Blending +!TP_HLREC_LABEL;Highlight Reconstruction +!TP_HLREC_LUMINANCE;Luminance Recovery +!TP_HLREC_METHOD;Method: +!TP_HSVEQUALIZER_CHANNEL;HSV Channel +!TP_HSVEQUALIZER_HUE;H +!TP_HSVEQUALIZER_LABEL;HSV Equalizer +!TP_HSVEQUALIZER_NEUTRAL;Neutral +!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_FILEDLGFILTERANY;Any files +!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_OUTPUTDLGLABEL;Select Output ICC Profile... +!TP_ICM_OUTPUTPROFILE;Output Profile +!TP_ICM_PREFERREDPROFILE;Preferred DCP profile +!TP_ICM_PREFERREDPROFILE_1;Daylight +!TP_ICM_PREFERREDPROFILE_2;Tungsten +!TP_ICM_PREFERREDPROFILE_3;Fluorescent +!TP_ICM_PREFERREDPROFILE_4;Flash +!TP_ICM_SAVEREFERENCE;Save Reference Image for Profiling +!TP_ICM_TONECURVE;Use DCP's tone curve +!TP_ICM_TONECURVE_TOOLTIP;Enable to use tone curves that may be contained in DCP profiles. +!TP_ICM_WORKINGPROFILE;Working Profile +!TP_IMPULSEDENOISE_LABEL;Impulse Noise Reduction +!TP_IMPULSEDENOISE_THRESH;Threshold +!TP_LABCURVE_RSTPRO_TOOLTIP;Can be used with the Chromaticity slider and the CC curve. +!TP_LABCURVE_LCREDSK;Restrict LC to red and skin tones +!TP_LABCURVE_LCREDSK_TIP;If enabled, LC Curve (Luminance According to Chromaticity) is limited to red and skin tones\nIf disabled, applies on all tones +!TP_LABCURVE_BRIGHTNESS;Brightness +!TP_LABCURVE_BWTONING;B&W toning +!TP_LABCURVE_BWTONING_TIP;With the B&W toning option enabled, the Lab Chromaticity, CC, CH and LC curves are not in effect.\nToning can be achieved using the a and b curves +!TP_LABCURVE_CHROMATICITY;Chromaticity +!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 the chromaticity +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to the hue +!TP_LABCURVE_CURVEEDITOR_LC;LC +!TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminance according to the chromaticity +!TP_LABCURVE_LABEL;Lab Adjustments +!TP_LABCURVE_RSTPROTECTION;Red and Skin Tones Protection +!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_LUMADENOISE_EDGETOLERANCE;Edge Tolerance +!TP_LUMADENOISE_LABEL;Luminance Noise Reduction +!TP_LUMADENOISE_RADIUS;Radius +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset exposure controls to neutral values +!TP_PERSPECTIVE_HORIZONTAL;Horizontal +!TP_PERSPECTIVE_LABEL;Perspective +!TP_PERSPECTIVE_VERTICAL;Vertical +!TP_PREPROCESS_GREENEQUIL;Green Equilibration +!TP_PREPROCESS_HOTDEADPIXFILT;Hot/Dead pixel filter +!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 (leader) +!TP_RAWEXPOS_LINEAR;White Point: Linear Corr. Factor +!TP_RAWEXPOS_PRESER;White Point: HL Preserving Corr. (EV) +!TP_RAWEXPOS_TWOGREEN;Two greens together +!TP_RAW_ALLENHANCE;Post-Demosaic Artifact/Noise Reduction +!TP_RAW_DCBENHANCE;DCB Enhancement Step +!TP_RAW_DCBITERATIONS;Number of DCB Iterations +!TP_RAW_DMETHOD;Method +!TP_RAW_LABEL;Demosaicing +!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_FULLSIZE;Full Image Size: +!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_RED;R +!TP_ROTATE_DEGREE;Degree +!TP_ROTATE_LABEL;Rotate +!TP_ROTATE_SELECTLINE;Select Straight Line +!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_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_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 the hue +!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_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 +!ZOOMBAR_DETAIL;Detail +!ZOOMBAR_HUGE;Huge +!ZOOMBAR_LARGE;Large +!ZOOMBAR_NORMAL;Normal +!ZOOMBAR_PREVIEW;Preview +!ZOOMBAR_SCALE;Scale +!ZOOMBAR_SMALL;Small +!ZOOMPANEL_100;(100%) +!ZOOMPANEL_NEWCROPWINDOW;Open (new) detail window +!ZOOMPANEL_ZOOM100;Zoom to 100%\nShortcut: 1 +!ZOOMPANEL_ZOOMFITSCREEN;Fit to screen\nShortcut: f +!ZOOMPANEL_ZOOMIN;Zoom In\nShortcut: + +!ZOOMPANEL_ZOOMOUT;Zoom Out\nShortcut: - + +# How to generate this UK file from the US one: +# grep -i color English\ \(US\) | sed "s/olor/olour/g" > English\ \(UK\) +# grep -i behavior English\ \(US\) | sed "s/ehavior/ehaviour/g" >> English\ \(UK\) +# egrep -vi "(color|behavior)" English\ \(US\) >> English\ \(UK\) +# Then remove leading "!" from the modified lines at the beginning of the UK file. diff --git a/rtdata/languages/English (US) b/rtdata/languages/English (US) new file mode 100644 index 000000000..7049e3b35 --- /dev/null +++ b/rtdata/languages/English (US) @@ -0,0 +1,1173 @@ +!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 +!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_DIALOGLABEL;Exif Filter +!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_SHARPENEDGE;Bypass Edge Sharpening +!EXPORT_BYPASS_SHARPENING;Bypass Sharpening +!EXPORT_BYPASS_SHARPENMICRO;Bypass Microcontrast +!EXPORT_BYPASS_SH_HQ;Bypass Shadow/Highlights (High Quality) +!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_ARRANGEMENTHINT;Change between vertical/horizontal alignment of thumbnails +!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 the path text box.\nEnter / Ctrl-Enter (in the File Browser) to browse there;\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_EXIFFILTERAPPLYHINT;Switch File Browser Exif Filter on/off +!FILEBROWSER_EXIFFILTERAPPLY;Apply +!FILEBROWSER_EXIFFILTERLABEL;Exif Filter +!FILEBROWSER_EXIFFILTERSETTINGSHINT;Change settings of the Exif Filter +!FILEBROWSER_EXIFFILTERSETTINGS;Setup +!FILEBROWSER_EXTPROGMENU;Open with +!FILEBROWSER_FLATFIELD;Flat Field +!FILEBROWSER_MOVETODARKFDIR;Move to dark frames directory +!FILEBROWSER_MOVETOFLATFIELDDIR;Move to flat fields directory +!FILEBROWSER_NEW_NAME;New name: +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!FILEBROWSER_PARTIALPASTEPROFILE;Paste - partial +!FILEBROWSER_PASTEPROFILE;Paste +!FILEBROWSER_POPUPCANCELJOB;Cancel job +!FILEBROWSER_POPUPCOLORLABEL0;Label: None +!FILEBROWSER_POPUPCOLORLABEL1;Label: Red +!FILEBROWSER_POPUPCOLORLABEL2;Label: Yellow +!FILEBROWSER_POPUPCOLORLABEL3;Label: Green +!FILEBROWSER_POPUPCOLORLABEL4;Label: Blue +!FILEBROWSER_POPUPCOLORLABEL5;Label: Purple +!FILEBROWSER_POPUPCOLORLABEL;Color label +!FILEBROWSER_POPUPCOPYTO;Copy to... +!FILEBROWSER_POPUPFILEOPERATIONS;File Operations +!FILEBROWSER_POPUPMOVEEND;Move to end of Queue +!FILEBROWSER_POPUPMOVEHEAD;Move to head of Queue +!FILEBROWSER_POPUPMOVETO;Move to... +!FILEBROWSER_POPUPOPEN;Open +!FILEBROWSER_POPUPPROCESSFAST;Put to Queue (Fast export) +!FILEBROWSER_POPUPPROCESS;Put to Queue +!FILEBROWSER_POPUPPROFILEOPERATIONS;Processing Profile Operations +!FILEBROWSER_POPUPRANK1;Rank 1 * +!FILEBROWSER_POPUPRANK2;Rank 2 ** +!FILEBROWSER_POPUPRANK3;Rank 3 *** +!FILEBROWSER_POPUPRANK4;Rank 4 **** +!FILEBROWSER_POPUPRANK5;Rank 5 ***** +!FILEBROWSER_POPUPRANK;Rank +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_POPUPREMOVESUBMENU;Remove +!FILEBROWSER_POPUPREMOVE;Delete +!FILEBROWSER_POPUPRENAME;Rename +!FILEBROWSER_POPUPSELECTALL;Select all +!FILEBROWSER_POPUPTRASH;Move to trash +!FILEBROWSER_POPUPUNRANK;Unrank +!FILEBROWSER_POPUPUNTRASH;Remove from trash +!FILEBROWSER_PROCESSINGSETTINGSHINT;Set the file format and output directory +!FILEBROWSER_PROCESSINGSETTINGS;Settings +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!FILEBROWSER_QUERYHINT;Type a partial filename to search for.\nCtrl-F to focus the Find text box (in the File Browser).\nEnter to commence search. +!FILEBROWSER_QUERYLABEL; Find: +!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 +!FILEBROWSER_SHOWQUEUEHINT;Show content of the processing queue +!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-` +!FILEBROWSER_SHOWUNRANKHINT;Show unranked images.\nShortcut: ` +!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_USETEMPLATE;Use template: +!FILEBROWSER_ZOOMINHINT;Increase thumbnail size.\nShortcut: + +!FILEBROWSER_ZOOMOUTHINT;Decrease thumbnail size.\nShortcut: - +!GENERAL_ABOUT;About +!GENERAL_AFTER;After +!GENERAL_BEFORE;Before +!GENERAL_CANCEL;Cancel +!GENERAL_DISABLED;Disabled +!GENERAL_DISABLE;Disable +!GENERAL_ENABLED;Enabled +!GENERAL_ENABLE;Enable +!GENERAL_FILE;File +!GENERAL_HIGH_QUALITY;High quality +!GENERAL_LANDSCAPE;Landscape +!GENERAL_LOAD;Load +!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 +!GENERAL_YES;Yes +!HISTOGRAM_BUTTON_BAR;RGB +!HISTOGRAM_BUTTON_B;B +!HISTOGRAM_BUTTON_G;G +!HISTOGRAM_BUTTON_L;L +!HISTOGRAM_BUTTON_RAW;Raw +!HISTOGRAM_BUTTON_R;R +!HISTOGRAM_LABEL;Histogram +!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_FULL;Toggle full or scaled 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;Brightness +!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 Exposure +!HISTORY_MSG_13;Exposure Clipping +!HISTORY_MSG_14;Luminance Brightness +!HISTORY_MSG_15;Luminance 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;Sharpening Radius +!HISTORY_MSG_22;Sharpening Amount +!HISTORY_MSG_23;Sharpening Threshold +!HISTORY_MSG_24;Sharpen only edges +!HISTORY_MSG_25;Sharpening Edge Detection Radius +!HISTORY_MSG_26;Sharpening Edge Tolerance +!HISTORY_MSG_27;Sharpening halo control +!HISTORY_MSG_28;Halo Control Amount +!HISTORY_MSG_29;Sharpening Method +!HISTORY_MSG_30;Deconvolution Radius +!HISTORY_MSG_31;Deconvolution Amount +!HISTORY_MSG_32;Deconvolution Damping +!HISTORY_MSG_33;Deconvolution 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;Color Temperature +!HISTORY_MSG_40;White Balance 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;Edge Sensitive Color Denoising +!HISTORY_MSG_50;Shadow/Highlight +!HISTORY_MSG_51;Highlights +!HISTORY_MSG_52;Shadows +!HISTORY_MSG_53;Highlight Tonal Width +!HISTORY_MSG_54;Shadow Tonal Width +!HISTORY_MSG_55;Local Contrast +!HISTORY_MSG_56;Shadow/Highlight 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;Lens Distortion Correction +!HISTORY_MSG_63;Snapshot Selected +!HISTORY_MSG_64;Crop Photo +!HISTORY_MSG_65;CA correction +!HISTORY_MSG_66;Highlight Recovery +!HISTORY_MSG_67;Highlight Recovery Amount +!HISTORY_MSG_68;Highlight Recovery Method +!HISTORY_MSG_69;Working Color Space +!HISTORY_MSG_70;Output Color Space +!HISTORY_MSG_71;Input Color Space +!HISTORY_MSG_72;Vignetting correction +!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 Enabled +!HISTORY_MSG_82;Profile Changed +!HISTORY_MSG_83;High Quality Shadows/Highlights +!HISTORY_MSG_84;Perspective Correction +!HISTORY_MSG_85;Lens Correction Profile +!HISTORY_MSG_86;Wavelet Equalizer +!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 +!HISTORY_MSG_92;NR - Gamma +!HISTORY_MSG_93;Contrast by Detail Levels Value +!HISTORY_MSG_94;Contrast by Detail Levels +!HISTORY_MSG_95;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;RGB Saturation +!HISTORY_MSG_101;HSV EQ -- Hue +!HISTORY_MSG_102;HSV EQ -- Saturation +!HISTORY_MSG_103;HSV EQ -- Value +!HISTORY_MSG_104;HSV Equalizer +!HISTORY_MSG_105;Defringing +!HISTORY_MSG_106;Defringing Radius +!HISTORY_MSG_107;Defringing Threshold +!HISTORY_MSG_108;Highlight Compr. Threshold +!HISTORY_MSG_109;Resize Bounding Box +!HISTORY_MSG_110;Resizing applies to +!HISTORY_MSG_111;Avoid color shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;Red and Skin Tones Protection +!HISTORY_MSG_114;DCB Iterations +!HISTORY_MSG_115;False Color Iterations +!HISTORY_MSG_116;Enhanced DCB +!HISTORY_MSG_117;Raw Red CA Correction +!HISTORY_MSG_118;Raw Blue CA Correction +!HISTORY_MSG_119;Line Denoise +!HISTORY_MSG_120;Green Equil. Threshold +!HISTORY_MSG_121;Raw Auto CA +!HISTORY_MSG_122;Auto Dark Frame +!HISTORY_MSG_123;Dark Frame File +!HISTORY_MSG_124;Linear Exp. Correction +!HISTORY_MSG_125;Exp. Correction Preserving HL +!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;Gamma +!HISTORY_MSG_134;Gamma Position +!HISTORY_MSG_135;Gamma free +!HISTORY_MSG_136;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 Green Together +!HISTORY_MSG_142;Edges Sharpening - Iterations +!HISTORY_MSG_143;Edges Sharpening - Quantity +!HISTORY_MSG_144;Microcontrast - Quantity +!HISTORY_MSG_145;Microcontrast - Uniformity +!HISTORY_MSG_146;Edges Sharpening +!HISTORY_MSG_147;Edges Sharpening - 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;Vibrance - Pastel tones +!HISTORY_MSG_153;Vibrance - Saturated tones +!HISTORY_MSG_154;Vibrance - Protect skin tones +!HISTORY_MSG_155;Vibrance - Avoid color shift +!HISTORY_MSG_156;Vibrance - Link pastel and saturated tones +!HISTORY_MSG_157;Vibrance - Pastel/Saturated threshold +!HISTORY_MSG_158;Strength +!HISTORY_MSG_159;Edge Stopping +!HISTORY_MSG_160;Scale +!HISTORY_MSG_161;Reweighting Iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_163;RGB Curves - R +!HISTORY_MSG_164;RGB Curves - G +!HISTORY_MSG_165;RGB Curves - B +!HISTORY_MSG_166;Neutral Levels +!HISTORY_MSG_167;B&W toning +!HISTORY_MSG_168;'CC' curve +!HISTORY_MSG_169;'CH' curve +!HISTORY_MSG_170;Vibrance - Curve +!HISTORY_MSG_171;'LC' curve +!HISTORY_MSG_172;Restrict LC to red and skin tones +!HISTORY_MSG_173;NR - Luminance Detail +!HISTORY_NEWSNAPSHOTAS;As... +!HISTORY_NEWSNAPSHOT;Add +!HISTORY_NEWSSDIALOGLABEL;Label of the snapshot: +!HISTORY_NEWSSDIALOGTITLE;Add new snapshot +!HISTORY_SETTO;Set to +!HISTORY_SNAPSHOTS;Snapshots +!HISTORY_SNAPSHOT;Snapshot +!ICMPANEL_FILEDLGFILTERANY;Any files +!ICMPANEL_FILEDLGFILTERICM;Color profiles +!ICMPANEL_GAMMABEFOREINPUT;Color Profile Applies Gamma +!ICMPANEL_INPUTCAMERA;Camera Default +!ICMPANEL_INPUTCUSTOM;Custom +!ICMPANEL_INPUTDLGLABEL;Select Input Color Profile... +!ICMPANEL_INPUTEMBEDDED;Use Embedded, if possible +!ICMPANEL_INPUTPROFILE;Input Color Profile +!ICMPANEL_NOICM;No ICM: sRGB Output +!ICMPANEL_OUTPUTDLGLABEL;Select Output Color Profile... +!ICMPANEL_OUTPUTPROFILE;Output Color Profile +!ICMPANEL_SAVEREFERENCE;Save reference image for profiling +!ICMPANEL_WORKINGPROFILE;Working Color Profile +!IMAGEAREA_DETAILVIEW;Detail View +!IPTCPANEL_AUTHORHINT;Name of the creator of the object, e.g. writer, photographer or graphic artist (By-line). +!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_EXIT;Exit +!MAIN_BUTTON_FULLSCREEN;Fullscreen +!MAIN_BUTTON_PREFERENCES;Preferences +!MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Put current image to processing queue.\nShortcut: Ctrl+Q +!MAIN_BUTTON_QUEUE;Put to Queue +!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_ERRORDURINGIMAGESAVING;Error during image saving +!MAIN_MSG_EXITJOBSINQUEUEINFO;Unprocessed images in the queue will be lost on exit. +!MAIN_MSG_EXITJOBSINQUEUEQUEST;Are you sure you want to exit? There are unprocessed images waiting in the queue. +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue processed first. +!MAIN_MSG_JOBSINQUEUE;job(s) in the queue +!MAIN_MSG_NAVIGATOR;Navigator +!MAIN_MSG_PLACES;Places +!MAIN_MSG_QOVERWRITE;Do you want to overwrite it? +!MAIN_TAB_BASIC;Basic +!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; Export +!MAIN_TAB_EXPOSURE;Exposure +!MAIN_TAB_EXPOSURE_TOOLTIP;Shortcut: Alt-E +!MAIN_TAB_FILTER; Filter +!MAIN_TAB_ICM;ICM +!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_TOGGLE_BEFORE_AFTER;B|A +!MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 8 +!MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 0 +!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_HIDEFP;Show/Hide the bottom panel (directory and file browser).\nShortcut: F +!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_PREFERENCES;Set preferences +!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_SAVEAS;Save image to a specific folder +!MAIN_TOOLTIP_SAVE;Save image to the default folder +!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;CA correction +!PARTIALPASTE_CHANNELMIXER;Channel mixer +!PARTIALPASTE_COARSETRANS;90° rotation / flipping +!PARTIALPASTE_COLORBOOST;Color boost +!PARTIALPASTE_COLORDENOISE;Color denoise +!PARTIALPASTE_COLORGROUP;Color Related Settings +!PARTIALPASTE_COLORMIXER;Color mixer +!PARTIALPASTE_COLORSHIFT;Color shift +!PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto fill +!PARTIALPASTE_COMPOSITIONGROUP;Composition Settings +!PARTIALPASTE_CROP;Crop +!PARTIALPASTE_DARKFRAMEAUTOSELECT;Dark frame auto select +!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;FF auto select +!PARTIALPASTE_FLATFIELDBLURRADIUS;FF blur radius +!PARTIALPASTE_FLATFIELDBLURTYPE;FF blur type +!PARTIALPASTE_FLATFIELDFILE;Flat field (FF) File +!PARTIALPASTE_HLRECONSTRUCTION;Highlight reconstruction +!PARTIALPASTE_HLRECOVERYAMOUNT;Highlight recovery amount +!PARTIALPASTE_HLRECOVERYTHRESHOLD;Highlight recovery threshold +!PARTIALPASTE_HLRECOVERY;Highlight recovery +!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_LUMADENOISE;Luminance noise reduction +!PARTIALPASTE_LUMINANCEGROUP;Luminance related settings +!PARTIALPASTE_METAICMGROUP;Metadata/Color Management Settings +!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 level +!PARTIALPASTE_RAWEXPOS_LINEAR;White point linear corr. factor +!PARTIALPASTE_RAWEXPOS_PRESER;White point HL preserving corr. (EV) +!PARTIALPASTE_RAWGROUP;Raw Settings +!PARTIALPASTE_RAW_ALLENHANCE;Apply post demosaic artifact/noise reduction +!PARTIALPASTE_RAW_DCBENHANCE;Apply DCB enhancement step +!PARTIALPASTE_RAW_DCBITERATIONS;Number of DCB iterations +!PARTIALPASTE_RAW_DMETHOD;Demosaic method +!PARTIALPASTE_RAW_FALSECOLOR;Demosaic false color suppression 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_WAVELETEQUALIZER;Wavelet equalizer +!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_BEHAVIOR;Behavior +!PREFERENCES_BLINKCLIPPED;Blink clipped areas +!PREFERENCES_CACHECLEARALL;Clear All +!PREFERENCES_CACHECLEARPROFILES;Clear Processing 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_CACHESTRAT1;Prefer Speed to Low Memory Consumption +!PREFERENCES_CACHESTRAT2;Prefer Low Memory Consumption to Speed +!PREFERENCES_CACHESTRAT;Cache Strategy +!PREFERENCES_CACHETHUMBFORM;Cache thumbnail format +!PREFERENCES_CACHETHUMBHEIGHT;Maximal thumbnail height +!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.\nReceives command line parameters to allow a rules-based processing profile generation:\n[raw/JPG path] [default processing profile path] [f-number] [exposure in secs] [focal length in mm] [ISO] [lens] [camera] +!PREFERENCES_CUSTPROFBUILDPATH;Executable path +!PREFERENCES_CUSTPROFBUILD;Custom Processing Profile Builder +!PREFERENCES_CUTOVERLAYBRUSH;Crop mask color/transparency +!PREFERENCES_DARKFRAMEFOUND;Found +!PREFERENCES_DARKFRAMESHOTS;shots +!PREFERENCES_DARKFRAMETEMPLATES;templates +!PREFERENCES_DARKFRAME;Dark Frame +!PREFERENCES_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_DEMOSAICINGALGO;Demosaicing Algorithm +!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_FORIMAGE;For non-raw photos +!PREFERENCES_FORRAW;For raw photos +!PREFERENCES_GIMPPATH;GIMP installation directory +!PREFERENCES_GTKTHEME;GTK default +!PREFERENCES_HINT;Hint +!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_LIVETHUMBNAILS;Live Thumbnails (slower) +!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_OUTDIRHINT;You can use the following formatting strings:\n%f, %d1, %d2, ..., %p1, %p2, ..., %r\n\nThese formatting strings refer to the different parts of the photo's pathname or some attributes of the photo.\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\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_OUTDIRTEMPLATEHINT;You can use the following formatting strings:\n%f, %d1, %d2, ..., %p1, %p2, ..., %r\n\nThese formatting strings refer to the different parts of the photo's pathname or some attributes of the photo.\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\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_SELECTFONT;Select font +!PREFERENCES_SELECTICCDIRDLG;Select Color Profile Directory... +!PREFERENCES_SELECTLANG;Select language +!PREFERENCES_SELECTMONITORPROFDLG;Select Color Profile of the Display... +!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_SHOWONLYRAW;Show only raw files +!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). On Windows use "SystemDefault", "SystemAsterisk" 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_OUTPUT;Output Options +!PREFERENCES_TAB_SOUND;Sounds +!PREFERENCES_THUMBSIZE;Thumbnail Size +!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_USESYSTEMTHEME;Use system theme +!PREFERENCES_WORKFLOW;Layout +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_FILEDLGFILTERANY;Any files +!PROFILEPANEL_FILEDLGFILTERPP;Processing profiles +!PROFILEPANEL_LABEL;Processing Profiles +!PROFILEPANEL_LOADDLGLABEL;Load Processing Parameters... +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_PCUSTOM;Custom +!PROFILEPANEL_PFILE;From file +!PROFILEPANEL_PLASTPHOTO;Last Photo +!PROFILEPANEL_PLASTSAVED;Last Saved +!PROFILEPANEL_PROFILE;Profile +!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_BADPIXELS;Bad pixels... +!PROGRESSBAR_CACORRECTION;CA correction... +!PROGRESSBAR_DARKFRAME;Darkframe... +!PROGRESSBAR_DECODING;Decoding raw file... +!PROGRESSBAR_DEMOSAICING;Demosaicing... +!PROGRESSBAR_GREENEQUIL;Green equilibrating... +!PROGRESSBAR_LINEDENOISE;Line denoise... +!PROGRESSBAR_LOADINGTHUMBS;Loading thumbnails... +!PROGRESSBAR_LOADING;Loading image... +!PROGRESSBAR_LOADJPEG;Loading JPEG file... +!PROGRESSBAR_LOADPNG;Loading PNG file... +!PROGRESSBAR_LOADTIFF;Loading TIFF file... +!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... +!PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!QINFO_FOCALLENGTH;Focal length +!QINFO_ISO;ISO +!QINFO_LENS;Lens +!QINFO_NOEXIF;Exif data not available. +!SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists +!SAVEDLG_FILEFORMAT;File format +!SAVEDLG_JPEGQUAL;JPEG Quality +!SAVEDLG_JPGFILTER;JPEG files +!SAVEDLG_PNGCOMPR;PNG Compression +!SAVEDLG_PNGFILTER;PNG files +!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\nthe 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 +!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_CACORRECTION_BLUE;Blue +!TP_CACORRECTION_LABEL;CA 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: [ +!TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotate right.\nShortcut: ] +!TP_COARSETRAF_TOOLTIP_VFLIP;Flip vertically +!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_CHROMA;Chrominance +!TP_DIRPYRDENOISE_GAMMA;Gamma +!TP_DIRPYRDENOISE_LABEL;Noise Reduction (raw images only) +!TP_DIRPYRDENOISE_LDETAIL;Luminance Detail +!TP_DIRPYRDENOISE_LUMA;Luminance +!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 +!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 +!TP_EXPOSURE_BLACKLEVEL;Black +!TP_EXPOSURE_BRIGHTNESS;Brightness +!TP_EXPOSURE_CLIP;Clip +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in auto level's operation +!TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Highlight Recovery Threshold +!TP_EXPOSURE_COMPRHIGHLIGHTS;Highlight Recovery Amount +!TP_EXPOSURE_COMPRSHADOWS;Shadow Recovery +!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_WEIGHTEDSTD;Weighted Standard +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Saturation and Value Blending +!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_HLREC_BLEND;Blend +!TP_HLREC_CIELAB;CIELab Blending +!TP_HLREC_COLOR;Color Propagation +!TP_HLREC_LABEL;Highlight Reconstruction +!TP_HLREC_LUMINANCE;Luminance Recovery +!TP_HLREC_METHOD;Method: +!TP_HSVEQUALIZER_CHANNEL;HSV Channel +!TP_HSVEQUALIZER_HUE;H +!TP_HSVEQUALIZER_LABEL;HSV Equalizer +!TP_HSVEQUALIZER_NEUTRAL;Neutral +!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_FILEDLGFILTERANY;Any files +!TP_ICM_FILEDLGFILTERICM;Color profiles +!TP_ICM_INPUTCAMERAICC;Auto-matched camera-specific color 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_OUTPUTDLGLABEL;Select Output ICC Profile... +!TP_ICM_OUTPUTPROFILE;Output Profile +!TP_ICM_PREFERREDPROFILE;Preferred DCP profile +!TP_ICM_PREFERREDPROFILE_1;Daylight +!TP_ICM_PREFERREDPROFILE_2;Tungsten +!TP_ICM_PREFERREDPROFILE_3;Fluorescent +!TP_ICM_PREFERREDPROFILE_4;Flash +!TP_ICM_SAVEREFERENCE;Save Reference Image for Profiling +!TP_ICM_TONECURVE;Use DCP's tone curve +!TP_ICM_TONECURVE_TOOLTIP;Enable to use tone curves that may be contained in DCP profiles. +!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\nand apply Munsell correction +!TP_LABCURVE_RSTPRO_TOOLTIP;Can be used with the Chromaticity slider and the CC curve. +!TP_LABCURVE_LCREDSK;Restrict LC to red and skin tones +!TP_LABCURVE_LCREDSK_TIP;If enabled, LC Curve (Luminance According to Chromaticity) is limited to red and skin tones\nIf disabled, applies on all tones +!TP_LABCURVE_BRIGHTNESS;Brightness +!TP_LABCURVE_BWTONING;B&W toning +!TP_LABCURVE_BWTONING_TIP;With the B&W toning option enabled, the Lab Chromaticity, CC, CH and LC curves are not in effect.\nToning can be achieved using the a and b curves +!TP_LABCURVE_CHROMATICITY;Chromaticity +!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 the chromaticity +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to the hue +!TP_LABCURVE_CURVEEDITOR_LC;LC +!TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminance according to the chromaticity +!TP_LABCURVE_LABEL;Lab Adjustments +!TP_LABCURVE_RSTPROTECTION;Red and Skin Tones Protection +!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_LUMADENOISE_EDGETOLERANCE;Edge Tolerance +!TP_LUMADENOISE_LABEL;Luminance Noise Reduction +!TP_LUMADENOISE_RADIUS;Radius +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset exposure controls to neutral values +!TP_PERSPECTIVE_HORIZONTAL;Horizontal +!TP_PERSPECTIVE_LABEL;Perspective +!TP_PERSPECTIVE_VERTICAL;Vertical +!TP_PREPROCESS_GREENEQUIL;Green Equilibration +!TP_PREPROCESS_HOTDEADPIXFILT;Hot/Dead pixel filter +!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 (leader) +!TP_RAWEXPOS_LINEAR;White Point: Linear Corr. Factor +!TP_RAWEXPOS_PRESER;White Point: HL Preserving Corr. (EV) +!TP_RAWEXPOS_TWOGREEN;Two greens together +!TP_RAW_ALLENHANCE;Post-Demosaic Artifact/Noise Reduction +!TP_RAW_DCBENHANCE;DCB Enhancement Step +!TP_RAW_DCBITERATIONS;Number of DCB Iterations +!TP_RAW_DMETHOD;Method +!TP_RAW_FALSECOLOR;False Color Suppression Steps +!TP_RAW_LABEL;Demosaicing +!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_FULLSIZE;Full Image Size: +!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_RED;R +!TP_ROTATE_DEGREE;Degree +!TP_ROTATE_LABEL;Rotate +!TP_ROTATE_SELECTLINE;Select Straight Line +!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_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_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 the hue +!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_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 +!ZOOMBAR_DETAIL;Detail +!ZOOMBAR_HUGE;Huge +!ZOOMBAR_LARGE;Large +!ZOOMBAR_NORMAL;Normal +!ZOOMBAR_PREVIEW;Preview +!ZOOMBAR_SCALE;Scale +!ZOOMBAR_SMALL;Small +!ZOOMPANEL_100;(100%) +!ZOOMPANEL_NEWCROPWINDOW;Open (new) detail window +!ZOOMPANEL_ZOOM100;Zoom to 100%\nShortcut: 1 +!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..d55b9fbc6 --- /dev/null +++ b/rtdata/languages/Espanol @@ -0,0 +1,1278 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) **PUT ALL THE CONTRIBUTORS HERE** + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#00 Espanol +#01 15.1.2008: keenonkites, first translation +#02 03.03.2008: Ioritz Ibarguren, corrections +#03 05.04.2008: keenonkites, completed for 2.4m1 +#04 09.04.2008: Ramon, partly corrected (part of 2.3) +#05 29.04.2008: Ramon, small correction +#06 09.06.2008: Ramon, Adaptions regarding 2.4m1 and others +#07 20.09.2008: keenonkites, first version for 2.4m2 +#08 19.12.2008: keenonkites, first version for 2.4beta4 +#09 07.12.2010: rickydh, some translations of untranslated keys for 3.0 alpha1 +#10 25.12.2011 plores, translation improvement, translation of untranslated strings +ABOUT_TAB_BUILD;Versión +ABOUT_TAB_CREDITS;Créditos +ABOUT_TAB_LICENSE;Licencia +ABOUT_TAB_SPLASH;Splash +ADJUSTER_RESET_TO_DEFAULT;Restablece los valores predeterminados +BATCHQUEUE_AUTOSTART;Inicio automático +BATCH_PROCESSING;Proceso por lotes +CURVEEDITOR_CURVE;Curva +CURVEEDITOR_CURVES;Curvas +CURVEEDITOR_CUSTOM;Personalizado +CURVEEDITOR_DARKS;Penumbras +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 lineal +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_DIALOGLABEL;Filtro Exif +EXIFFILTER_EXPOSURECOMPENSATION;Compensación de exposición (EV) +EXIFFILTER_FILETYPE;Tipo de archivo +EXIFFILTER_FOCALLEN;Distancia focal +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Objetivo +EXIFFILTER_METADATAFILTER;Activar filtros de metadatos +EXIFFILTER_SHUTTER;Tiempo de exposición +EXIFPANEL_ADDEDIT;Agregar/Cambiar +EXIFPANEL_ADDEDITHINT;Agregar atributo nuevo o cambiar atributo +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Introducir valor +EXIFPANEL_ADDTAGDLG_SELECTTAG;Seleccionar atributo +EXIFPANEL_ADDTAGDLG_TITLE;Agregar/Cambiar atributo +EXIFPANEL_KEEP;Conservar +EXIFPANEL_KEEPHINT;Conserva las etiquetas seleccionadas al escribir el archivo de salida +EXIFPANEL_REMOVE;Borrar +EXIFPANEL_REMOVEHINT;Quita las etiquetas seleccionadas al escribir el archivo de salida +EXIFPANEL_RESET;Reiniciar +EXIFPANEL_RESETALL;Reiniciar todo +EXIFPANEL_RESETALLHINT;Reiniciar todos los atributos a los valores originales +EXIFPANEL_RESETHINT;Reiniciar atributos seleccionados a los valores originales +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 mediante niveles de detalle +EXPORT_BYPASS_LUMADENOISE;Saltar Reducción de ruido de luminancia +EXPORT_BYPASS_RAW_ALL_ENHANCE;Saltar Reducción de ruido/artefactos postdemosaicado +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 paso de mejora DCB +EXPORT_BYPASS_RAW_DCB_ITERATIONS;Saltar [raw] Iteraciones DCB +EXPORT_BYPASS_RAW_DF;Saltar [raw] Imagen en oscuridad +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_SHARPENEDGE;Saltar Enfoque de bordes +EXPORT_BYPASS_SHARPENING;Saltar Enfoque +EXPORT_BYPASS_SHARPENMICRO;Saltar Microcontraste +EXPORT_BYPASS_SH_HQ;Saltar Sombras/Luces altas (Alta calidad) +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. Este método se recomienda 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 para Exportación Rápida +EXPORT_RAW_DMETHOD;Método de demosaicado +EXPORT_RESIZEMETHOD;Método de cambio de tamaño +FILEBROWSER_ADDDELTEMPLATE;Añadir/Borrar plantillas... +FILEBROWSER_APPLYPROFILE;Aplicar perfil +FILEBROWSER_APPLYPROFILE_PARTIAL;Aplicar perfil (parcial) +FILEBROWSER_ARRANGEMENTHINT;Cambiar disposición de las miniaturas entre horizontal y vertical +FILEBROWSER_AUTODARKFRAME;Auto Imagen en oscuridad +FILEBROWSER_AUTOFLATFIELD;Auto Campo plano +FILEBROWSER_BROWSEPATHBUTTONHINT;Pulsar para examinar la carpeta seleccionada +FILEBROWSER_BROWSEPATHHINT;Escribir el path a examinar (Ctrl-o poner el foco en el cuadro de texto,Ctrl-Enter para examinar en el Explorador de Archivos) +FILEBROWSER_CACHECLEARFROMFULL;Limpiar del caché (completo) +FILEBROWSER_CACHECLEARFROMPARTIAL;Limpiar del caché (parcial) +FILEBROWSER_CACHE;Cache +FILEBROWSER_CLEARPROFILE;Borrar perfil +FILEBROWSER_COPYPROFILE;Copiar perfil +FILEBROWSER_CURRENT_NAME;Nombre actual: +FILEBROWSER_DARKFRAME;Imagen en oscuridad +FILEBROWSER_DELETEDLGLABEL;Confirmación de borrar archivos +FILEBROWSER_DELETEDLGMSGINCLPROC;¿Seguro que quieres borrar los %1 archivos seleccionados INCLUYENDO la versión procesada en la cola? +FILEBROWSER_DELETEDLGMSG;¿Seguro que quieres borrar los %1 archivos seleccionados? +FILEBROWSER_EMPTYTRASH;Vaciar papelera +FILEBROWSER_EMPTYTRASHHINT;Borrar archivos de la papelera definitivamente +FILEBROWSER_EXEC_CPB;Ejecutar generador de perfiles de imagen del usuario +FILEBROWSER_EXIFFILTERAPPLY;Aplicar +FILEBROWSER_EXIFFILTERAPPLYHINT;Activar/desactivar filtro Exif en el explorador de archivos +FILEBROWSER_EXIFFILTERLABEL;Filtro Exif +FILEBROWSER_EXIFFILTERSETTINGS;Ajuste +FILEBROWSER_EXIFFILTERSETTINGSHINT;Cambiar ajustes del filtro Exif +FILEBROWSER_EXTPROGMENU;Abrir con +FILEBROWSER_FLATFIELD;Campo plano +FILEBROWSER_MOVETODARKFDIR;Mover a carpeta de Imágenes en oscuridad +FILEBROWSER_MOVETOFLATFIELDDIR;Mover a carpeta de campo plano +FILEBROWSER_NEW_NAME;Nuevo nombre: +FILEBROWSER_PARTIALPASTEPROFILE;Pegar perfil parcialmente +FILEBROWSER_PASTEPROFILE;Pegar perfil +FILEBROWSER_POPUPCANCELJOB;Cancelar trabajo +FILEBROWSER_POPUPCOLORLABEL;Etiquetar con un color +FILEBROWSER_POPUPCOLORLABEL0;Etiqueta: Ninguna +FILEBROWSER_POPUPCOLORLABEL1;Etiqueta: Rojo +FILEBROWSER_POPUPCOLORLABEL2;Etiqueta: Amarillo +FILEBROWSER_POPUPCOLORLABEL3;Etiqueta: Verde +FILEBROWSER_POPUPCOLORLABEL4;Etiqueta: Azul +FILEBROWSER_POPUPCOLORLABEL5;Etiqueta: Púrpura +FILEBROWSER_POPUPCOPYTO;Copiar a... +FILEBROWSER_POPUPFILEOPERATIONS;Operaciones con archivos +FILEBROWSER_POPUPMOVEEND;Desplazar al fin de la cola +FILEBROWSER_POPUPMOVEHEAD;Desplazar al comienzo de la cola +FILEBROWSER_POPUPMOVETO;Mover a... +FILEBROWSER_POPUPOPEN;Abrir +FILEBROWSER_POPUPPROCESS;Poner en la cola +FILEBROWSER_POPUPPROCESSFAST;Poner en la cola (exportación rápida) +FILEBROWSER_POPUPPROFILEOPERATIONS;Operaciones con perfiles +FILEBROWSER_POPUPRANK;Valorar +FILEBROWSER_POPUPRANK1;Valorar con 1 estrella +FILEBROWSER_POPUPRANK2;Valorar con 2 estrellas +FILEBROWSER_POPUPRANK3;Valorar con 3 estrellas +FILEBROWSER_POPUPRANK4;Valorar con 4 estrellas +FILEBROWSER_POPUPRANK5;Valorar con 5 estrellas +FILEBROWSER_POPUPREMOVE;Borrar del sistema +FILEBROWSER_POPUPREMOVEINCLPROC;Borrar del sistema junto con resultado batch +FILEBROWSER_POPUPRENAME;Renombrar +FILEBROWSER_POPUPSELECTALL;Seleccionar todo +FILEBROWSER_POPUPTRASH;Desplazar a la papelera +FILEBROWSER_POPUPUNRANK;Quitar valoración +FILEBROWSER_POPUPUNTRASH;Salvar de la papelera +FILEBROWSER_PROCESSINGSETTINGS;Ajustes +FILEBROWSER_PROCESSINGSETTINGSHINT;Ajustar formato de archivo y carpeta de salida +FILEBROWSER_QUERYBUTTONHINT;Borrar la búsqueda +FILEBROWSER_QUERYHINT;Escribir una parte del nombre del archivo a buscar \nCtrl-f poner el foco (en el explorador de archivos);\nEnter para buscar +FILEBROWSER_QUERYLABEL; Buscar: +FILEBROWSER_RENAMEDLGLABEL;Renombrar archivo +FILEBROWSER_RENAMEDLGMSG;Renombrar archivo "%1"a: +FILEBROWSER_SELECTDARKFRAME;Seleccionar imagen en oscuridad... +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;Mostrar todas imágenes de la carpeta +FILEBROWSER_SHOWEDITEDHINT;Mostrar imágenes editadas 7 +FILEBROWSER_SHOWEDITEDNOTHINT;Mostrar imágenes no editadas 6 +FILEBROWSER_SHOWEXIFINFO;Mostrar información EXIF i +FILEBROWSER_SHOWQUEUEHINT;Mostrar contenido de la cola de procesamiento +FILEBROWSER_SHOWRANK1HINT;Mostrar imágenes con 1 estrella +FILEBROWSER_SHOWRANK2HINT;Mostrar imágenes con 2 estrellas +FILEBROWSER_SHOWRANK3HINT;Mostrar imágenes con 3 estrellas +FILEBROWSER_SHOWRANK4HINT;Mostrar imágenes con 4 estrellas +FILEBROWSER_SHOWRANK5HINT;Mostrar imágenes con 5 estrellas +FILEBROWSER_SHOWRECENTLYSAVEDHINT;Mostrar imágenes guardadas recientemente Alt-7 +FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Mostrar imágenes no guardadas recientemente Alt-6 +FILEBROWSER_SHOWTRASHHINT;Mostrar contenido de la papelera +FILEBROWSER_SHOWUNCOLORHINT;Mostrar imágenes sin etiqueta de color Alt-` +FILEBROWSER_SHOWUNRANKHINT;Mostrar imágenes sin valoración +FILEBROWSER_STARTPROCESSING;Iniciar procesamiento +FILEBROWSER_STARTPROCESSINGHINT;Iniciar procesamiento de imágenes en la cola +FILEBROWSER_STOPPROCESSING;Parar procesamiento +FILEBROWSER_STOPPROCESSINGHINT;Parar procesamiento de imágenes en la cola +FILEBROWSER_THUMBSIZE;Tamaño miniatura +FILEBROWSER_TOOLTIP_STOPPROCESSING;Iniciar procesamiento automáticamente cuando llega un nuevo trabajo +FILEBROWSER_USETEMPLATE;Utilizar plantilla: +FILEBROWSER_ZOOMINHINT;Agrandar miniatura +FILEBROWSER_ZOOMOUTHINT;Reducir miniatura +GENERAL_ABOUT;Acerca de +GENERAL_AFTER;Después +GENERAL_BEFORE;Antes +GENERAL_CANCEL;Cancelar +GENERAL_DISABLE;Desactivar +GENERAL_DISABLED;Desactivado +GENERAL_ENABLE;Activar +GENERAL_ENABLED;Activado +GENERAL_FILE;Archivo +GENERAL_HIGH_QUALITY;Alta calidad +GENERAL_LANDSCAPE;Paisaje +GENERAL_LOAD;Abrir +GENERAL_NA;n/a +GENERAL_NONE;Ninguno +GENERAL_NO;No +GENERAL_OK;Aceptar +GENERAL_PORTRAIT;Retrato +GENERAL_SAVE;Guardar +GENERAL_UNCHANGED;(Sin cambios) +GENERAL_YES;Sí +HISTOGRAM_BUTTON_B;B +HISTOGRAM_BUTTON_B;B +HISTOGRAM_BUTTON_G;G +HISTOGRAM_BUTTON_L;L +HISTOGRAM_BUTTON_R;R +HISTOGRAM_BUTTON_RAW;Raw +HISTOGRAM_LABEL;Histograma +HISTOGRAM_TOOLTIP_B;Mostrar/Ocultar histograma AZUL +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_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_R;Mostrar/Ocultar histograma ROJO +HISTOGRAM_TOOLTIP_RAW;Mostrar/ocultar histograma RAW +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 tono +HISTORY_MSG_12;Exposición automática +HISTORY_MSG_13;Recorte de exposición +HISTORY_MSG_14;Luminancia - Brillo +HISTORY_MSG_15;Luminancia - Contraste +HISTORY_MSG_16;Luminancia - Negro +HISTORY_MSG_17;Luminancia - Compr. de luces altas +HISTORY_MSG_18;Luminancia - Compr. de sombras +HISTORY_MSG_19;Luminancia - Curva +HISTORY_MSG_20;Enfoque +HISTORY_MSG_21;Enfoque - Radio +HISTORY_MSG_22;Enfoque - Cantidad +HISTORY_MSG_23;Enfoque - Umbral +HISTORY_MSG_24;Enfocar 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;Control de Halo - Cantidad +HISTORY_MSG_29;Enfoque - Método +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;Evitar recorte de colores +HISTORY_MSG_35;Limitador de saturación +HISTORY_MSG_36;Límite de saturación +HISTORY_MSG_37;Aumento de colores +HISTORY_MSG_38;Equilibrio de Blancos - Método +HISTORY_MSG_39;Temperatura de color +HISTORY_MSG_40;Equilibrio de Blancos - Tinte +HISTORY_MSG_41;Curva de tono modo 1 +HISTORY_MSG_42;Curva de tono 2 +HISTORY_MSG_43;Curva de tono 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;Red. ruido de color - Sensible a bordes +HISTORY_MSG_50;Herramienta Sombras/Luces altas +HISTORY_MSG_51;Aumento de luces altas +HISTORY_MSG_52;Aumento de sombras +HISTORY_MSG_53;Luces altas - Ancho tonal +HISTORY_MSG_54;Sombras - Ancho tonal +HISTORY_MSG_55;Contraste local +HISTORY_MSG_56;Sombras/Luces altas - 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 del objetivo +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;Alta calidad Sombras/Luces Altas +HISTORY_MSG_84;Corrección de perspectiva +HISTORY_MSG_85;Coeficientes wavelet +HISTORY_MSG_86;Ecualizador wavelet +HISTORY_MSG_87;Reducción ruido impulsivo +HISTORY_MSG_88;Umbral reducc. ruido impuls. +HISTORY_MSG_89;Reducción de ruido +HISTORY_MSG_90;NR - Luminancia +HISTORY_MSG_91;NR - Crominancia +HISTORY_MSG_92;NR - Gamma +HISTORY_MSG_93;Contraste por niveles de detalle - Valor +HISTORY_MSG_94;Contraste por niveles de detalle +HISTORY_MSG_95;Cromaticidad +HISTORY_MSG_96;Curva 'a' +HISTORY_MSG_97;Curva 'b' +HISTORY_MSG_98;Método de desmosaicado +HISTORY_MSG_99;Preprocesamiento +HISTORY_MSG_100;Saturación RGB +HISTORY_MSG_101;Ecualizador HSV - Tono +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 compresión de luces altas +HISTORY_MSG_109;Tamaño del rectángulo limitador +HISTORY_MSG_110;Cambio de tamaño aplica a +HISTORY_MSG_111;Evitar recorte de colores +HISTORY_MSG_112;Limitador de saturación +HISTORY_MSG_113;Protección de rojos y tonos de piel +HISTORY_MSG_114;Iteraciones DCB +HISTORY_MSG_115;Iteraciones de falso color +HISTORY_MSG_116;DCB mejorado +HISTORY_MSG_117;Corrección CA - Rojo +HISTORY_MSG_118;Corrección CA - Azul +HISTORY_MSG_119;Filtro de ruido de línea +HISTORY_MSG_120;Umbral de equilibrado de verde +HISTORY_MSG_121;Corrección automática CA +HISTORY_MSG_122;Auto selección archivo imagen en oscuridad +HISTORY_MSG_123;Archivo de imagen en oscuridad +HISTORY_MSG_124;Corrección lineal de exposición +HISTORY_MSG_125;Corrección de exposición preservando HL +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 +HISTORY_MSG_134;Posición de gamma +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 de ambos verdes juntos +HISTORY_MSG_142;Claridad - Pasos +HISTORY_MSG_143;Claridad - Intensidad de gradiente +HISTORY_MSG_144;Microcontraste - cantidad +HISTORY_MSG_145;Microcontraste - uniformidad +HISTORY_MSG_146;Enfoque Claridad - Activado +HISTORY_MSG_147;Claridad - Sólo luminancia +HISTORY_MSG_148;Microcontraste +HISTORY_MSG_149;Microcontraste - matriz 3x3 +HISTORY_MSG_150;Reducción de artefactos/ruido post desmosaicado +HISTORY_MSG_151;Vibranza +HISTORY_MSG_152;Vibranza - Tonos pastel +HISTORY_MSG_153;Vibranza - Tonos saturados +HISTORY_MSG_154;Vibranza - Proteger tonos de piel +HISTORY_MSG_155;Vibranza - Evitar deriva de color +HISTORY_MSG_156;Vibranza - Enlazar tonos pastel y saturados +HISTORY_MSG_157;Vibranza - Umbral pastel/saturado +HISTORY_MSG_158;Intensidad +HISTORY_MSG_159;Parada en los bordes +HISTORY_MSG_160;Escala +HISTORY_MSG_161;Iteraciones de reponderación +HISTORY_MSG_162;Mapeo de tonos +HISTORY_MSG_163;Curvas RGB - R +HISTORY_MSG_164;Curvas RGB - G +HISTORY_MSG_165;Curvas RGB - B +HISTORY_MSG_166;Niveles neutros +HISTORY_MSG_167;Toneado B/N +HISTORY_MSG_168;Curva 'Cc' +HISTORY_MSG_169;Curva 'Ch' +HISTORY_MSG_170;Vibranza - Curva +HISTORY_MSG_171;Curva 'LC' +HISTORY_MSG_172;Restringir 'LC' a los tonos rojos y de piel +HISTORY_MSG_173;NR - Detalle de la luminancia +HISTORY_NEWSNAPSHOT;Instantánea nueva +HISTORY_NEWSNAPSHOTAS;Como... +HISTORY_NEWSSDIALOGLABEL;Etiqueta de la instantánea: +HISTORY_NEWSSDIALOGTITLE;Añadir instantánea nueva +HISTORY_SETTO;Ajustado a +HISTORY_SNAPSHOT;Instantánea +HISTORY_SNAPSHOTS;Instantáneas +ICMPANEL_FILEDLGFILTERANY;Cualquier archivo +ICMPANEL_FILEDLGFILTERICM;Archivos de perfiles ICC +ICMPANEL_GAMMABEFOREINPUT;El perfil aplica Gamma +ICMPANEL_INPUTCAMERA;Valores predeterminados de la cámara +ICMPANEL_INPUTCUSTOM;A medida +ICMPANEL_INPUTDLGLABEL;Seleccionar perfil ICC de entrada... +ICMPANEL_INPUTEMBEDDED;Usar incrustado, si es posible +ICMPANEL_INPUTPROFILE;Perfil de entrada +ICMPANEL_NOICM;Ningún MIC: Salida sRGB +ICMPANEL_OUTPUTDLGLABEL;Seleccionar perfil ICC de salida... +ICMPANEL_OUTPUTPROFILE;Perfil de salida +ICMPANEL_SAVEREFERENCE;Guardar imagen de referencia para el perfilado +ICMPANEL_WORKINGPROFILE;Perfil de trabajo +IMAGEAREA_DETAILVIEW;Vista de detalle +IPTCPANEL_AUTHOR;Autor +IPTCPANEL_AUTHORHINT;Nombre del creador del objeto, por ejemplo el escritor, el fotógrafo o el artista gráfico (By-line). +IPTCPANEL_AUTHORSPOSITION;Tratamiento o título del autor +IPTCPANEL_AUTHORSPOSITIONHINT;Título del creador o de los creadores del objeto (By-line Title). +IPTCPANEL_CAPTION;Leyenda +IPTCPANEL_CAPTIONHINT;Descripción textual de la información (Caption - Abstract). +IPTCPANEL_CAPTIONWRITER;Autor de la leyenda +IPTCPANEL_CAPTIONWRITERHINT;Nombre de la persona que escribió, modificó o corrigió la imagen o leyenda/resumen (Writer - Editor). +IPTCPANEL_CATEGORY;Categoría +IPTCPANEL_CATEGORYHINT;Código de tres letras que identifica el sujeto de la imagen en opinión del proveedor (Category). +IPTCPANEL_CITY;Ciudad +IPTCPANEL_CITYHINT;Origen de la imagen: Ciudad (City). +IPTCPANEL_COPYHINT;Copiar ajustes IPTC al portapapeles +IPTCPANEL_COPYRIGHT;Derechos de autor +IPTCPANEL_COPYRIGHTHINT;Cualquier llamada de atención necesaria sobre los derechos de autor (Copyright Notice). +IPTCPANEL_COUNTRY;País +IPTCPANEL_COUNTRYHINT;Origen de la imagen: Pais (Country - Primary Location Name). +IPTCPANEL_CREDIT;Créditos +IPTCPANEL_CREDITHINT;Identifica el proveedor de la imagen, no tiene que ser el creador o el propietario (Credit). +IPTCPANEL_DATECREATED;Fecha de creación +IPTCPANEL_DATECREATEDHINT;Fecha de creación del contenido intelectual de la imagen; Formato: AAAAMMDD (Date Created). +IPTCPANEL_EMBEDDED;Incrustado +IPTCPANEL_EMBEDDEDHINT;Reiniciar a los datos IPTC incrustados en el archivo de la imagen +IPTCPANEL_HEADLINE;Titular +IPTCPANEL_HEADLINEHINT;Una anotación publicable que provee una sinopsis de los contenidos de la imagen (Headline). +IPTCPANEL_INSTRUCTIONS;Instrucciones +IPTCPANEL_INSTRUCTIONSHINT;Otras instrucciones editoriales sobre el uso de la imagen (Special Instructions). +IPTCPANEL_KEYWORDS;Palabras clave +IPTCPANEL_KEYWORDSHINT;Palabras clave que hacen la búsqueda de la imagen mas fácil (Keywords). +IPTCPANEL_PASTEHINT;Pegar ajustes IPTC desde el portapapeles +IPTCPANEL_PROVINCE;Estado/Provincia +IPTCPANEL_PROVINCEHINT;Origen de la imagen: Estado/Provincia (Province-State). +IPTCPANEL_RESET;Reiniciar +IPTCPANEL_RESETHINT;Reiniciar a los ajustes predeterminados del perfil. +IPTCPANEL_SOURCE;Fuente +IPTCPANEL_SOURCEHINT;Propietario original del contenido intelectual de la imagen (Source). +IPTCPANEL_SUPPCATEGORIES;Categorías suplementarias +IPTCPANEL_SUPPCATEGORIESHINT;Afinado del sujeto de la imagen (Supplemental Categories). +IPTCPANEL_TITLE;Título +IPTCPANEL_TITLEHINT;Referencia concisa de la imagen (Object Name). +IPTCPANEL_TRANSREFERENCE;Ref. trans. original +IPTCPANEL_TRANSREFERENCEHINT;Un código que representa el lugar de la transmisión original (Original Transmission Reference). +MAIN_BUTTON_EXIT;Exit +MAIN_BUTTON_FULLSCREEN;Pantalla completa +MAIN_BUTTON_PREFERENCES;Preferencias +MAIN_BUTTON_PUTTOQUEUE;Poner en la cola +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Añadir imagen actual a la cola de procesamiento Ctrl+Q +MAIN_BUTTON_QUEUE;Poner en la cola +MAIN_BUTTON_SAVE;Guardar imagen +MAIN_BUTTON_SAVEAS;Como... +MAIN_BUTTON_SAVE_TOOLTIP;Guardar imagen actual Ctrl+S +MAIN_BUTTON_SENDTOEDITOR;Abrir con editor +MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Editar imagen actual en editor externo Ctrl+E +MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Mostrar/ocultar todos los paneles laterales m +MAIN_BUTTON_UNFULLSCREEN;Salir de Pantalla completa +MAIN_FRAME_BATCHQUEUE;Cola por lotes +MAIN_FRAME_BATCHQUEUE_TOOLTIP; Cola por lotes Ctrl-F3 +MAIN_FRAME_EDITOR;Editor +MAIN_FRAME_EDITOR_TOOLTIP; Editor Ctrl-F4 +MAIN_FRAME_FILEBROWSER;Explorador de archivos +MAIN_FRAME_FILEBROWSER_TOOLTIP; Explorador de archivos 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 con editor. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Por favor ajuste las preferencias. +MAIN_MSG_EMPTYFILENAME;Nombre de archivo no especificado +MAIN_MSG_ERRORDURINGIMAGESAVING;Error al guardar imagen +MAIN_MSG_EXITJOBSINQUEUEINFO;Saliendo del programa, las imágenes no terminadas en la cola se perderán. +MAIN_MSG_EXITJOBSINQUEUEQUEST;¿Estás seguro de que quieres salir? Hay imágenes no terminadas en la cola. +MAIN_MSG_JOBSINQUEUE;trabajo(s) en cola +MAIN_MSG_NAVIGATOR;Navegador +MAIN_MSG_PLACES;Ubicaciones +MAIN_MSG_QOVERWRITE;¿Quieres reemplazarlo? +MAIN_TAB_BASIC;Básicos +MAIN_TAB_COLOR;Color +MAIN_TAB_COLOR_TOOLTIP;Alt-c +MAIN_TAB_DETAIL;Detalle +MAIN_TAB_DETAIL_TOOLTIP;Alt-d +MAIN_TAB_DEVELOP;Revelar +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPORT; Exportar +MAIN_TAB_EXPOSURE;Exposición +MAIN_TAB_EXPOSURE_TOOLTIP;Alt-e +MAIN_TAB_FILTER;Filtro +MAIN_TAB_ICM;GIC +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadatos +MAIN_TAB_METADATA_TOOLTIP;Alt-m +MAIN_TAB_RAW;RAW +MAIN_TAB_RAW_TOOLTIP;Alt-r +MAIN_TAB_TAGGING;Etiquetado +MAIN_TAB_TRANSFORM;Transformar +MAIN_TAB_TRANSFORM_TOOLTIP;Alt-t +MAIN_TOGGLE_BEFORE_AFTER;A|D +MAIN_TOOLTIP_BACKCOLOR0;Color de fondo de la previsualización: Color del tema\nAtajo de teclado: 8 +MAIN_TOOLTIP_BACKCOLOR1;Color de fondo de la previsualización: Negro\nAtajo de teclado: 9 +MAIN_TOOLTIP_BACKCOLOR2;Color de fondo de la previsualización: Blanco\nAtajo de teclado: 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_HIDEFP;Mostrar/Ocultar panel inferior (explorador carpetas y arch. tecla F) +MAIN_TOOLTIP_HIDEHP;Mostrar/Ocultar panel izquierdo (incluyendo historial, tecla H) +MAIN_TOOLTIP_INDCLIPPEDH;Indicación de luces altas recortadas +MAIN_TOOLTIP_INDCLIPPEDS;Indicación de sombras recortadas +MAIN_TOOLTIP_PREFERENCES;Ajustar preferencias +MAIN_TOOLTIP_PREVIEWB;Previsualización Canal azul +MAIN_TOOLTIP_PREVIEWFOCUSMASK;Previsualización Máscara de foco +MAIN_TOOLTIP_PREVIEWG;Previsualización Canal verde +MAIN_TOOLTIP_PREVIEWR;Previsualización Canal rojo +MAIN_TOOLTIP_PREVIEWL;Previsualización Luminosidad\n0.299*R + 0.587*G + 0.114*B +MAIN_TOOLTIP_QINFO; Información breve de la imagen +MAIN_TOOLTIP_SAVE;Guardar imagen a la carpeta predeterminada +MAIN_TOOLTIP_SAVEAS;Guardar imagen a una carpeta seleccionada +MAIN_TOOLTIP_SHOWHIDELP1;Mostrar/ocultar el panel izquierdo l +MAIN_TOOLTIP_SHOWHIDERP1;Mostrar/ocultar el panel derecho Alt-l +MAIN_TOOLTIP_SHOWHIDETP1;Mostrar/ocultar el panel superior Shift-l +MAIN_TOOLTIP_THRESHOLD;Umbral +MAIN_TOOLTIP_TOGGLE;Cambiar vista antes/despué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_NA;x = n/a, y = n/a +PARTIALPASTE_BASICGROUP;Ajustes básicos +PARTIALPASTE_CACORRECTION;Corrección de aberraciones cromáticas +PARTIALPASTE_CHANNELMIXER;Mezclador de canales +PARTIALPASTE_COARSETRANS;Rotar 90 grados / voltear +PARTIALPASTE_COLORBOOST;Aumento de colores +PARTIALPASTE_COLORDENOISE;Reducción de ruido de color +PARTIALPASTE_COLORGROUP;Ajustes de color +PARTIALPASTE_COLORMIXER;Mezclador de canal +PARTIALPASTE_COLORSHIFT;Cambio de colores +PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto relleno +PARTIALPASTE_COMPOSITIONGROUP;Ajustes relativos a la transformación +PARTIALPASTE_CROP;Recortar +PARTIALPASTE_DARKFRAMEAUTOSELECT;Auto Selección de imagen en oscuridad +PARTIALPASTE_DARKFRAMEFILE;Archivo de imagen en oscuridad +PARTIALPASTE_DEFRINGE;Eliminar borde púrpura +PARTIALPASTE_DETAILGROUP;Ajustes de detalle +PARTIALPASTE_DIALOGLABEL;Pegar perfil de procesamiento parcialmente +PARTIALPASTE_DIRPYRDENOISE;Reducción de ruido +PARTIALPASTE_DIRPYREQUALIZER;Contraste mediante niveles de detalle +PARTIALPASTE_DISTORTION;Distorsión +PARTIALPASTE_EPD;Mapeo de tonos +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_HLRECONSTRUCTION;Recuperación de luces altas +PARTIALPASTE_HLRECOVERY;Recuperación de luces altas +PARTIALPASTE_HSVEQUALIZER;Ecualizador HSV +PARTIALPASTE_ICMGAMMA;Gamma de salida +PARTIALPASTE_ICMSETTINGS;Ajustes GIC +PARTIALPASTE_IMPULSEDENOISE;Reducción de ruido impulsivo +PARTIALPASTE_IPTCINFO;Informaciones IPTC +PARTIALPASTE_LABCURVE;Curva Lab +PARTIALPASTE_LENSGROUP;Ajustes relativos al objetivo +PARTIALPASTE_LUMACURVE;Curva de luminancia +PARTIALPASTE_LUMADENOISE;Reducción de ruido de luminancia +PARTIALPASTE_LUMINANCEGROUP;Ajustes de luminancia +PARTIALPASTE_METAICMGROUP;Ajustes de metadatos/GIC +PARTIALPASTE_MICROCONTRAST;Microcontraste +PARTIALPASTE_PERSPECTIVE;Perspectiva +PARTIALPASTE_PREPROCESS_GREENEQUIL;Equilibrio del verde +PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Aplicar filtro de píxel dañado +PARTIALPASTE_PREPROCESS_LINEDENOISE;Filtro de ruido de línea +PARTIALPASTE_RAWCACORR_AUTO;Auto corrección CA +PARTIALPASTE_RAWCACORR_CABLUE;CA Azul +PARTIALPASTE_RAWCACORR_CARED;CA Rojo +PARTIALPASTE_RAWEXPOS_BLACK;Nivel de negro +PARTIALPASTE_RAWEXPOS_LINEAR;Factor de corr. lineal de exposición +PARTIALPASTE_RAWEXPOS_PRESER;Corr. de exposición preservando HL (EV) +PARTIALPASTE_RAWGROUP;Ajustes Raw +PARTIALPASTE_RAW_ALLENHANCE;Aplicar reducción de ruido/artefactos post-desmosaicado +PARTIALPASTE_RAW_DCBENHANCE;Aplicar paso de mejora DCB +PARTIALPASTE_RAW_DCBITERATIONS;Número de iteraciones DCB +PARTIALPASTE_RAW_DMETHOD;Método de demosaicado +PARTIALPASTE_RAW_FALSECOLOR;Pasos de supresión de falso color de demosaicado +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;Microcontraste +PARTIALPASTE_VIBRANCE;Vibranza +PARTIALPASTE_VIGNETTING;Corrección de viñeteo +PARTIALPASTE_WAVELETEQUALIZER;Ecualizador de wavelets +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 automáticamente el perfil de sistema operativo del monitor principal +PREFERENCES_BATCH_PROCESSING;Proceso por lotes +PREFERENCES_BEHAVIOR;Comportamiento +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;Ajustar memoria intermedia +PREFERENCES_CACHESTRAT1;Preferir velocidad sobre consumo de memoria +PREFERENCES_CACHESTRAT2;Preferir consumo de memoria bajo sobre velocidad +PREFERENCES_CACHESTRAT;Estrategia de la 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_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_CUSTPROFBUILD;Programa generador de perfiles de imagen del usuario +PREFERENCES_CUSTPROFBUILDHINT;Archivo ejecutable (o script) invocado para generar un nuevo perfil inicial para una imagen.\nRecibe parámetros de línea de orden para permitir la generación de perfiles .pp3 basada en reglas:\n[Path RAW/JPG] [Path al perfil por omisión] [número f] [exposición en segundos] [longitud focal en mm] [ISO] [Lente] [Cámara] +PREFERENCES_CUSTPROFBUILDPATH;Path al programa ejecutable +PREFERENCES_CUTOVERLAYBRUSH;Pincel para ventana de recorte +PREFERENCES_DARKFRAME;Imagen en oscuridad +PREFERENCES_DARKFRAMEFOUND;Encontrado +PREFERENCES_DARKFRAMESHOTS;disparos +PREFERENCES_DARKFRAMETEMPLATES;plantillas +PREFERENCES_DATEFORMAT;Formato de fechas +PREFERENCES_DATEFORMATFRAME;Formato de fechas +PREFERENCES_DATEFORMATHINT;Se pueden usar las variables siguientes:\n%y : año\n%m : mes\n%d : dia\n\nPor ejemplo, la fecha en Argentina es:\n%d/%m/%y +PREFERENCES_DCBENHANCE;Aplicar paso mejora DCB +PREFERENCES_DCBITERATIONS;Número iteraciones DCB +PREFERENCES_DEFAULTLANG;Idioma predeterminado +PREFERENCES_DEFAULTTHEME;Estilo predeterminado +PREFERENCES_DEMOSAICINGALGO;Algoritmo de desmosaicado +PREFERENCES_DIRDARKFRAMES;Carpeta de imágenes en oscuridad +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;Otro mandato +PREFERENCES_EDITORLAYOUT;Aspecto 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 +PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Barra de herramientas del explorador en una sola fila (deseleccionar para pantallas de baja resolución) +PREFERENCES_FILEFORMAT;Formato de archivos +PREFERENCES_FLATFIELD;Campo plano +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_FORIMAGE;Para archivos de imágenes +PREFERENCES_FORRAW;Para archivos RAW +PREFERENCES_GIMPPATH;Carpeta de instalación de GIMP +PREFERENCES_GREENEQUIL;Equilibrado del verde +PREFERENCES_GTKTHEME;Estilo de GTK predeterminado +PREFERENCES_HINT;Consejo +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 de perfiles ICC +PREFERENCES_IMPROCPARAMS;Parámetros predeterminados de procesamiento de imágenes +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 interna RAW si no se ha editado +PREFERENCES_LANGAUTODETECT;Usar configuración de idioma del SO +PREFERENCES_LINEDENOISE;Filtro de ruido de línea +PREFERENCES_LIVETHUMBNAILS;Miniaturas 'en vivo' (más lento) +PREFERENCES_MENUGROUPEXTPROGS;Grupo "Abrir con" +PREFERENCES_MENUGROUPFILEOPERATIONS;Operaciones en un grupo de archivos +PREFERENCES_MENUGROUPLABEL;Etiquetado de grupo +PREFERENCES_MENUGROUPPROFILEOPERATIONS;Operaciones en un grupo de perfiles +PREFERENCES_MENUGROUPRANK;Puntuación de grupo +PREFERENCES_MENUOPTIONS;Opciones de menú +PREFERENCES_METADATA;Metadatos +PREFERENCES_MONITORICC;Perfil de pantalla +PREFERENCES_MULTITAB;Modo de varias pestañas +PREFERENCES_MULTITABDUALMON;Modo de varias pestañas, si está disponible en segundo monitor +PREFERENCES_OUTDIR;Carpeta de salida +PREFERENCES_OUTDIRFOLDER;Guardar en carpeta +PREFERENCES_OUTDIRFOLDERHINT;Guardar las imágenes creadas en una carpeta elegida +PREFERENCES_OUTDIRHINT;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_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_OVERLAY_FILENAMES;Superponer nombres de archivo en miniaturas +PREFERENCES_OVERWRITEOUTPUTFILE;Sobreescribir archivos de salida existentes +PREFERENCES_PANFACTORFRAME;Aceleración del panning +PREFERENCES_PANFACTORLABEL;Factor +PREFERENCES_PARSEDEXT;Extensiones analizadas +PREFERENCES_PARSEDEXTADD;Agregar extensión +PREFERENCES_PARSEDEXTADDHINT;Entra una extensión y pulsa este botón para agregar a la lista +PREFERENCES_PARSEDEXTDELHINT;Borrar extensión de la lista +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 con 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_SELECTFONT;Seleccionar fuente +PREFERENCES_SELECTICCDIRDLG;Seleccionar carpeta de perfiles ICC... +PREFERENCES_SELECTLANG;Seleccionar idioma +PREFERENCES_SELECTMONITORPROFDLG;Seleccionar perfil ICC de la pantalla... +PREFERENCES_SELECTTHEME;Seleccionar estilo +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_SHOWONLYRAW;Mostrar solo archivos RAW +PREFERENCES_SHOWPROFILESELECTOR;Mostrar selector de perfiles +PREFERENCES_SHTHRESHOLD;Umbral de sombras cortadas +PREFERENCES_SINGLETAB;Modo de pestaña única +PREFERENCES_SINGLETABVERTAB;Modo de pestaña única, pestañas verticales +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 +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_OUTPUT;Opciones de salida +PREFERENCES_TAB_SOUND;Sonidos +PREFERENCES_THUMBSIZE;Tamaño de miniaturas +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;Traspasar IPTC/XMP sin cambios al fichero de salida +PREFERENCES_USESYSTEMTHEME; Usar tema del sistema +PREFERENCES_WORKFLOW;Flujo de trabajo +PROFILEPANEL_FILEDLGFILTERANY;Cualquier archivo +PROFILEPANEL_FILEDLGFILTERPP;Perfiles de procesamiento +PROFILEPANEL_LABEL;Perfiles de procesamiento +PROFILEPANEL_LOADDLGLABEL;Cargar parámetros de procesamiento... +PROFILEPANEL_PCUSTOM;A medida +PROFILEPANEL_PFILE;Desde archivo +PROFILEPANEL_PLASTPHOTO;Última foto +PROFILEPANEL_PLASTSAVED;Último guardado +PROFILEPANEL_PROFILE;Perfil +PROFILEPANEL_SAVEDLGLABEL;Guardar parámetros de procesamiento... +PROFILEPANEL_TOOLTIPCOPY;Copiar parámetros de procesamiento al portapapeles +PROFILEPANEL_TOOLTIPLOAD;Cargar perfil de un archivo +PROFILEPANEL_TOOLTIPPASTE; Pegar perfil del portapapeles +PROFILEPANEL_TOOLTIPSAVE;Guardar perfil actual +PROGRESSBAR_BADPIXELS;Píxeles dañados... +PROGRESSBAR_CACORRECTION;Corrección CA... +PROGRESSBAR_DARKFRAME;Imagen en oscuridad... +PROGRESSBAR_DECODING;Descodificando archivo RAW... +PROGRESSBAR_DEMOSAICING;Interpolando mosaico... +PROGRESSBAR_GREENEQUIL;Equilibrado del verde... +PROGRESSBAR_LINEDENOISE;Eliminando ruido de línea... +PROGRESSBAR_LOADING;Abriendo imagen... +PROGRESSBAR_LOADINGTHUMBS;Cargando miniaturas... +PROGRESSBAR_LOADJPEG;Abriendo archivo JPEG... +PROGRESSBAR_LOADPNG;Abriendo archivo PNG... +PROGRESSBAR_LOADTIFF;Abriendo archivo TIFF... +PROGRESSBAR_PROCESSING;Procesando imagen... +PROGRESSBAR_READY;Listo. +PROGRESSBAR_SAVEJPEG;Guardando archivo JPEG... +PROGRESSBAR_SAVEPNG;Guardando archivo PNG... +PROGRESSBAR_SAVETIFF;Guardando archivo TIFF... +PROGRESSDLG_LOADING;Abriendo archivo... +PROGRESSDLG_PROCESSING;Procesando imagen... +PROGRESSDLG_PROFILECHANGEDINBROWSER;Perfil cambiado en explorador +PROGRESSDLG_SAVING;Guardando archivo... +QINFO_FOCALLENGTH;Longitud focal +QINFO_ISO;ISO +QINFO_LENS;Objetivo +QINFO_NOEXIF;No hay datos EXIF. +SAVEDLG_AUTOSUFFIX;Añade un sufijo automáticamente si el archivo existe +SAVEDLG_FILEFORMAT;Formato de archivo +SAVEDLG_JPEGQUAL;Calidad JPEG +SAVEDLG_JPGFILTER;Archivos JPEG +SAVEDLG_PNGCOMPR;Compresión PNG +SAVEDLG_PNGFILTER;Archivos PNG +SAVEDLG_PUTTOQUEUE;Poner en la cola +SAVEDLG_PUTTOQUEUEHEAD;Poner al principio de la cola +SAVEDLG_PUTTOQUEUETAIL;Poner al fin de la cola +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 +SHCSELECTOR_TOOLTIP;Pulsar el botón derecho del ratón para restablecer\nla posición de los tres deslizadores +THRESHOLDSELECTOR_B;Inferior +THRESHOLDSELECTOR_BL;Inferior izquierdo +THRESHOLDSELECTOR_BR;Inferior derecho +THRESHOLDSELECTOR_HINT;Pulsar la tecla Mayús para mover los puntos de control individuales. +THRESHOLDSELECTOR_T;Superior +THRESHOLDSELECTOR_TL;Superior izquierdo +THRESHOLDSELECTOR_TR;Superior derecho +TOOLBAR_TOOLTIP_CROP;Elección de recorte (tecla C) +TOOLBAR_TOOLTIP_HAND;Herramienta mano (tecla N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Elección de línea recta (tecla S) +TOOLBAR_TOOLTIP_WB;Muestrea equilibrio de blancos (tecla W) +TP_DISTORTION_AUTO;Auto corrección de distorsión +TP_CACORRECTION_BLUE;Azul +TP_CACORRECTION_LABEL;Corrección de aberraciones cromáticas +TP_CACORRECTION_RED;Rojo +TP_CHMIXER_BLUE;Azul +TP_CHMIXER_GREEN;Verde +TP_CHMIXER_LABEL;Mezclador de canal +TP_CHMIXER_RED;Rojo +TP_CHROMATABERR_LABEL;Aberración cromática +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 +TP_COARSETRAF_TOOLTIP_ROTLEFT;Rotar a la izquierda +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotar a la derecha +TP_COARSETRAF_TOOLTIP_VFLIP;Voltear verticalmente +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_SELECTCROP; Seleccionar recorte +TP_CROP_W;An +TP_CROP_X;x +TP_CROP_Y;y +TP_DARKFRAME_AUTOSELECT;Auto selección +TP_DARKFRAME_LABEL;Imagen en oscuridad +TP_DEFRINGE_LABEL;Quitar borde púrpura +TP_DEFRINGE_RADIUS;Radio +TP_DEFRINGE_THRESHOLD;Umbral +TP_DETAIL_AMOUNT;Cantidad +TP_DIRPYRDENOISE_CHROMA;Crominancia +TP_DIRPYRDENOISE_GAMMA;Gamma +TP_DIRPYRDENOISE_LABEL;Reducción de ruido +TP_DIRPYRDENOISE_LDETAIL;Detalle de la luminancia +TP_DIRPYRDENOISE_LUMA;Luminancia +TP_DIRPYREQUALIZER_LABEL;Contraste mediante 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; Corrección automática de distorsión +TP_DISTORTION_AUTO_TIP;(Experimental) Corrige automáticamente la distorsión de la lente para algunas cámaras (M4/3, algunas compactas DC, etc.) +TP_DISTORTION_LABEL;Distorsión +TP_EPD_EDGESTOPPING;Parada en los bordes +TP_EPD_LABEL;Mapeo de tonos +TP_EPD_REWEIGHTINGITERATES;Iteraciones de reponderación +TP_EPD_SCALE;Escala +TP_EPD_STRENGTH;Intensidad +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;Exposición +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 +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_COMPRHIGHLIGHTS;Compresión de luces altas +TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Umbral de recuperación de luces altas +TP_EXPOSURE_COMPRSHADOWS;Compresión de sombras +TP_EXPOSURE_CONTRAST;Contraste +TP_EXPOSURE_CURVEEDITOR1;Curva de tono 1 +TP_EXPOSURE_CURVEEDITOR2;Curva de tono 2 +TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Consultar la siguiente sección del manual para saber más sobre cómo obtener los mejores resultados con la curva doble:\nLa caja de herramientas > Pestaña Exposición > Panel de Exposición > Curva de tono +TP_EXPOSURE_EXPCOMP;Comp. de exposición +TP_EXPOSURE_LABEL;Exposició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_WEIGHTEDSTD;Estándar ponderado +TP_EXPOSURE_TCMODE_STANDARD;Estándar +TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Mezcla de saturación y valor +TP_EXPOSURE_TCMODE_VALBLENDING;Canal de valor +TP_EXPOSURE_SATURATION;Saturación +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_HLREC_BLEND;Mezcla +TP_HLREC_CIELAB;Superposición de CIELab +TP_HLREC_COLOR;Propagación de color +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 HSV +TP_HSVEQUALIZER_HUE;Tono +TP_HSVEQUALIZER_LABEL;Ecualizador HSV +TP_HSVEQUALIZER_NEUTRAL;Neutro +TP_HSVEQUALIZER_SAT;Saturación +TP_HSVEQUALIZER_VAL;Valor +TP_ICM_BLENDCMSMATRIX;Mezclar las luces altas con matriz +TP_ICM_BLENDCMSMATRIX_TOOLTIP;Permite recuperar luces altas quemadas cuando se usan perfiles ICC basados en LUT +TP_ICM_FILEDLGFILTERANY;Cualquier archivo +TP_ICM_FILEDLGFILTERICM;Archivos de perfiles ICC +TP_ICM_GAMMABEFOREINPUT;El perfil aplica gamma +TP_ICM_INPUTCAMERA;Valores predeterminados de la cámara +TP_ICM_INPUTCAMERA_TOOLTIP;Usa una matriz de color simple (default) en DCRAW o incluida en DNG +TP_ICM_INPUTCAMERAICC;Estándar de cámara o ICC +TP_ICM_INPUTCAMERAICC_TOOLTIP;Usa el perfil de color ICC default de RawTherapee. Más preciso que la matriz, pero sólo disponible para algunas cámaras. +TP_ICM_INPUTCUSTOM;A medida +TP_ICM_INPUTCUSTOM_TOOLTIP;Seleccione su propio perfil de color ICC para la cámara +TP_ICM_INPUTDLGLABEL;Seleccionar perfil ICC de entrada... +TP_ICM_INPUTEMBEDDED;Usar incrustado, si es posible +TP_ICM_INPUTEMBEDDED_TOOLTIP;Usar el perfil de color incluido en archivos no RAW +TP_ICM_INPUTNONE;Sin perfil +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;GIC +TP_ICM_NOICM;Ningún MIC: Salida sRGB +TP_ICM_OUTPUTDLGLABEL;Seleccionar perfil ICC de salida... +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_SAVEREFERENCE;Guardar imagen de referencia para el perfilado +TP_ICM_SAVEREFERENCEDLGLABEL;Guardar imagen de referencia para el perfilado +TP_ICM_TONECURVE;Usar curva de tono DCP +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;Reducc. ruido impulsivo +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\ny 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_CONTRAST;Contraste +TP_LABCURVE_CURVEEDITOR;Curva de luminancia +TP_LABCURVE_CURVEEDITOR_A_RANGE1;Verde saturado +TP_LABCURVE_CURVEEDITOR_A_RANGE2;Verde pastel +TP_LABCURVE_CURVEEDITOR_A_RANGE3;Rojo pastel +TP_LABCURVE_CURVEEDITOR_A_RANGE4;Rojo saturado +TP_LABCURVE_CURVEEDITOR_B_RANGE1;Azul saturado +TP_LABCURVE_CURVEEDITOR_B_RANGE2;Azul pastel +TP_LABCURVE_CURVEEDITOR_B_RANGE3;Amarillo pastel +TP_LABCURVE_CURVEEDITOR_B_RANGE4;Amarillo saturado +TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutros +TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Mates +TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastel +TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Saturados +TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Cromaticidad de acuerdo con la Cromaticidad +TP_LABCURVE_CURVEEDITOR_CCL_TOOLTIP;Luminancia de acuerdo con Cromaticidad - Tonos de piel y también Rojo -Amarillo - Azul - Verde +TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Cromaticidad de acuerdo con el Tono +TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminancia de acuerdo con la Cromaticidad +TP_LABCURVE_ENABLESATLIMITER;Activar limitador de saturación +TP_LABCURVE_LABEL;Curvas Lab +TP_LABCURVE_LCREDSK;Curva LC - Tonos rojos y de piel +TP_LABCURVE_LCREDSK_TIP;Si se activa, 'Curva LC' está limitada a los tonos rojos y de piel\nSi se desactiva, se actúa sobre todos los colores +TP_LABCURVE_RSTPROTECTION;Protección de rojos y tonos de 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;Objetivo / Geometría +TP_LENSPROFILE_FILEDLGFILTERLCP;Archivos de correción de lente +TP_LENSPROFILE_LABEL;Perfil de corrección de lente +TP_LENSPROFILE_USECA;Usar corrección de CA +TP_LENSPROFILE_USEDIST;Usar corrección de distorsión +TP_LENSPROFILE_USEVIGN;Usar 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_LUMADENOISE_EDGETOLERANCE;Tolerancia de bordes +TP_LUMADENOISE_LABEL;Reducción de ruido de luminancia +TP_LUMADENOISE_RADIUS;Radio +TP_MLMICRO_STRENGTH;Intensidad +TP_MLMICRO_UNIFORMITY;Uniformidad +TP_NEUTRAL;Neutro +TP_NEUTRAL_TIP;Restablecer controles de exposición a valores neutros +TP_PERSPECTIVE_HORIZONTAL;Horizontal +TP_PERSPECTIVE_LABEL;Perspectiva +TP_PERSPECTIVE_VERTICAL;Vertical +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_LABEL;Preprocesado +TP_PREPROCESS_LINEDENOISE;Filtro de ruido de línea +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_FALSECOLOR;Pasos de supresión de falso color +TP_RAW_LABEL;Desmosaicado +TP_RAWCACORR_AUTO;Auto corrección +TP_RAWCACORR_CABLUE;Azul +TP_RAWCACORR_CARED;Rojo +TP_RAWEXPOS_BLACKZERO;Nivel de negro: Verde 1 (director) +TP_RAWEXPOS_BLACKONE;Nivel de negro: Rojo +TP_RAWEXPOS_BLACKS;Niveles de negro +TP_RAWEXPOS_BLACKTWO;Nivel de negro: Azul +TP_RAWEXPOS_BLACKTHREE;Nivel de negro: Verde 2 +TP_RAWEXPOS_LINEAR;Factor de corrección lineal +TP_RAWEXPOS_PRESER;Corrección preservando HL (EV) +TP_RAWEXPOS_TWOGREEN;Los dos verdes juntos +TP_RAWPANEL_DEMOSAICING;Desmosaicado +TP_RAWPANEL_PREPROCESSING;Preprocesado +TP_RESIZE_APPLIESTO;Aplica a: +TP_RESIZE_BICUBIC;Bicúbica +TP_RESIZE_BICUBICSF;Bicúbica (más suave) +TP_RESIZE_BICUBICSH;Bicúbica (más enfocado) +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_FULLSIZE;Tamaño de imagen completo: +TP_RESIZE_H;Al: +TP_RESIZE_HEIGHT;Altura +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_W;An: +TP_RESIZE_WIDTH;Anchura +TP_RGBCURVES_LABEL;Curvas RGB +TP_RGBCURVES_CHANNEL;Canal +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_SHADOWSHLIGHTS_HIGHLIGHTS;Luces altas +TP_SHADOWSHLIGHTS_HLTONALW;Ancho tonal +TP_SHADOWSHLIGHTS_LABEL;Sombras/Luces altas +TP_SHADOWSHLIGHTS_LOCALCONTR;Contraste local +TP_SHADOWSHLIGHTS_RADIUS;Radio +TP_SHADOWSHLIGHTS_SHADOWS;Sombras +TP_SHADOWSHLIGHTS_SHTONALW;Ancho tonal +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_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;Tono de acuerdo con Tono +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_FLASH_HEADER;Flash +TP_WBALANCE_FLASH55;Leica +TP_WBALANCE_FLASH60;Estándar, Canon, Pentax, Olympus +TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +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_DAYLIGHT;Luz de día (soleado) +TP_WBALANCE_TEMPERATURE;Temperatura +TP_WBALANCE_TUNGSTEN;Tungsteno +ZOOMBAR_DETAIL;Detalle +ZOOMBAR_HUGE;Enorme +ZOOMBAR_LARGE;Grande +ZOOMBAR_NORMAL;Normal +ZOOMBAR_PREVIEW;Previsualización +ZOOMBAR_SCALE;Escala +ZOOMBAR_SMALL;Pequeño +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;Abrir (nueva) ventana de detalle +ZOOMPANEL_ZOOM100;Zoom al 100% 1 +ZOOMPANEL_ZOOMFITSCREEN;Ajustar a pantalla F +ZOOMPANEL_ZOOMIN;Aumentar Zoom + +ZOOMPANEL_ZOOMOUT;Reducir Zoom - + diff --git a/rtdata/languages/Euskara b/rtdata/languages/Euskara new file mode 100644 index 000000000..6c20ac2c8 --- /dev/null +++ b/rtdata/languages/Euskara @@ -0,0 +1,1209 @@ +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_DIALOGLABEL;Exif Filter +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_ARRANGEMENTHINT;Change between vertical/horizontal alignment of thumbnails +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_EXIFFILTERAPPLYHINT;Switch on/off exif filter of the file browser +FILEBROWSER_EXIFFILTERAPPLY;Apply +FILEBROWSER_EXIFFILTERLABEL;Exif Filter +FILEBROWSER_EXIFFILTERSETTINGSHINT;Change settings of the exif filter +FILEBROWSER_EXIFFILTERSETTINGS;Setup +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_POPUPRANK1;Rank 1 +FILEBROWSER_POPUPRANK2;Rank 2 +FILEBROWSER_POPUPRANK3;Rank 3 +FILEBROWSER_POPUPRANK4;Rank 4 +FILEBROWSER_POPUPRANK5;Rank 5 +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_PROCESSINGSETTINGSHINT;Set the file format and output directory +FILEBROWSER_PROCESSINGSETTINGS;Settings +FILEBROWSER_RENAMEDLGLABEL;Rename file +FILEBROWSER_RENAMEDLGMSG;Rename file "%1" to: +FILEBROWSER_SHOWDIRHINT;Show all images of the directory +FILEBROWSER_SHOWQUEUEHINT;Show content of the processing queue +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_LOAD;Ireki +GENERAL_NA;n/a +GENERAL_NO;Ez +GENERAL_OK;Onartu +GENERAL_PORTRAIT;Erretratua +GENERAL_SAVE;Gorde +GENERAL_YES;Bai +HISTOGRAM_LABEL;Histogram +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_NEWSNAPSHOTAS;Honela... +HISTORY_NEWSNAPSHOT;Argazki berria +HISTORY_NEWSSDIALOGLABEL;Argazkiaren etiketa: +HISTORY_NEWSSDIALOGTITLE;Argazki berria gehitu +HISTORY_SETTO;Honetara doitua +HISTORY_SNAPSHOTS;Argazkiak +HISTORY_SNAPSHOT;Argazkia +ICMPANEL_FILEDLGFILTERANY;Artxibo guztiak +ICMPANEL_FILEDLGFILTERICM;ICC profilen artxiboak +ICMPANEL_GAMMABEFOREINPUT;Profile applies Gamma +ICMPANEL_INPUTCAMERA;Kameraren jatorrizko balioak +ICMPANEL_INPUTCUSTOM;Neurrira +ICMPANEL_INPUTDLGLABEL;Sarrerako ICC profila hautatu... +ICMPANEL_INPUTEMBEDDED;Txertatutakoa erabili, egonez gero +ICMPANEL_INPUTPROFILE;Sarrerako profila +ICMPANEL_NOICM;ICM-rik ez: sRGB irteera +ICMPANEL_OUTPUTDLGLABEL;Irteerako ICC profila hautatu... +ICMPANEL_OUTPUTPROFILE;Irteera profila +ICMPANEL_SAVEREFERENCE;Save reference image for profiling +ICMPANEL_WORKINGPROFILE;Lan profila +IMAGEAREA_DETAILVIEW;Zehaztasun bista +IPTCPANEL_AUTHORHINT;Name of the creator of the object, e.g. writer, photographer or graphic artist (By-line). +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_EXIT;Exit +MAIN_BUTTON_PREFERENCES;Ezarpenak +MAIN_BUTTON_QUEUE;Put to queue +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_EXITJOBSINQUEUEINFO;Unprocessed images in the queue will be lost on exit. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Are you sure you want to exit? There are unprocessed images waiting in the queue. +MAIN_MSG_JOBSINQUEUE;lana(k) ilaran +MAIN_MSG_QOVERWRITE;Gainidatzi? +MAIN_TAB_BASIC;Oinarrizkoak +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_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;Bihurtu +MAIN_TOOLTIP_HIDEFP;Erakutsi/Ezkutatu behe panela (arakatzailea, shortcut key: F) +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_PREFERENCES;Ezarpenak doitu +MAIN_TOOLTIP_QINFO; Irudiaren informazio laburra +MAIN_TOOLTIP_SAVEAS;Irudia hautatutako karpeta batera gorde +MAIN_TOOLTIP_SAVE;Irudia lehenetsiriko karpetara gorde +PARTIALPASTE_BASICGROUP;Basic settings +PARTIALPASTE_CACORRECTION;C/A correction +PARTIALPASTE_COARSETRANS;90 deg rotation / flipping +PARTIALPASTE_COLORBOOST;Color boost +PARTIALPASTE_COLORDENOISE;Color denoise +PARTIALPASTE_COLORGROUP;Color related settings +PARTIALPASTE_COLORMIXER;Color mixer +PARTIALPASTE_COLORSHIFT;Color shift +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_HLRECOVERY;Highlight recovery +PARTIALPASTE_ICMSETTINGS;ICM settings +PARTIALPASTE_IPTCINFO;IPTC info +PARTIALPASTE_LENSGROUP;Lens related settings +PARTIALPASTE_LUMACURVE;Luminance curve +PARTIALPASTE_LUMADENOISE;Luminance noise reduction +PARTIALPASTE_LUMINANCEGROUP;Luminance related settings +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_CACHESTRAT1;Prefer Speed to Low Memory Consumption +PREFERENCES_CACHESTRAT2;Prefer Low Memory Consumption to Speed +PREFERENCES_CACHESTRAT;Cache Strategy +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_DEMOSAICINGALGO;Demosaikatze algoritmoa +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_HINT;Gomendioa +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_LIVETHUMBNAILS;Live Thumbnails (slower) +PREFERENCES_MONITORICC;Pantaila profilak +PREFERENCES_OUTDIRFOLDERHINT;Put the saved images to the seledted folder +PREFERENCES_OUTDIRFOLDER;Save to folder +PREFERENCES_OUTDIRHINT;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_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_SELECTICCDIRDLG;ICC profilen carpeta hautatu... +PREFERENCES_SELECTLANG;Hizkuntza hautatu +PREFERENCES_SELECTMONITORPROFDLG;Pantaila profilen karpeta hautatu... +PREFERENCES_SELECTTHEME;Select theme +PREFERENCES_SHOWBASICEXIF;Oinarrizko EXIF datuak bistaratu +PREFERENCES_SHOWDATETIME;Data eta ordua bistratu +PREFERENCES_SHOWONLYRAW;RAW artxiboak bakarrik erakutsi +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 +PREFERENCES_TAB_OUTPUT;Irteera aukerak +PREFERENCES_THUMBSIZE;Miniaturen tamaina +PROFILEPANEL_FILEDLGFILTERANY;Artxibo guztiak +PROFILEPANEL_FILEDLGFILTERPP;Prozesu profilak +PROFILEPANEL_LABEL;Prozesu profilak +PROFILEPANEL_LOADDLGLABEL;Profilaren aldagaiak ireki... +PROFILEPANEL_PCUSTOM;Neurrira +PROFILEPANEL_PFILE;Artxibotik +PROFILEPANEL_PLASTPHOTO;Azken argazkia +PROFILEPANEL_PLASTSAVED;Gordtako azkena +PROFILEPANEL_PROFILE;Profilak +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_DECODING;RAW artxiboa dekodetzen... +PROGRESSBAR_DEMOSAICING;Demosaikatzen... +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_FOCALLENGTH;Fokal luzera +QINFO_ISO;ISO +QINFO_LENS;Lens +QINFO_NOEXIF;Ez dago EXIF daturik. +SAVEDLG_FILEFORMAT;Artxiboaren formatua +SAVEDLG_JPEGQUAL;JPEG kalitatea +SAVEDLG_JPGFILTER;JPEG artxiboak +SAVEDLG_PNGCOMPR;PNG konpresioa +SAVEDLG_PNGFILTER;PNG artxiboak +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_OUTPUTDLGLABEL;Irteerako ICC profila hautatu... +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_LUMADENOISE_EDGETOLERANCE;Ertz tolerantzia +TP_LUMADENOISE_LABEL;Argitasun zarata murrizketa +TP_LUMADENOISE_RADIUS;Erradioa +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_FULLSIZE;Irudi tamaina osoa: +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 +ZOOMBAR_DETAIL;Xehetasuna +ZOOMBAR_HUGE;Ikaragarria +ZOOMBAR_LARGE;Handia +ZOOMBAR_NORMAL;Arrunta +ZOOMBAR_PREVIEW;Aurrebista +ZOOMBAR_SCALE;Eskala +ZOOMBAR_SMALL;Txikia + +#00 Euskara (Basque) +#01 03.03.2008 +#02 Ioritz Ibarguren +# + +!!!!!!!!!!!!!!!!!!!!!!!!! +! 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 +!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_SHARPENEDGE;Bypass Edge Sharpening +!EXPORT_BYPASS_SHARPENING;Bypass Sharpening +!EXPORT_BYPASS_SHARPENMICRO;Bypass Microcontrast +!EXPORT_BYPASS_SH_HQ;Bypass Shadow/Highlights (High Quality) +!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 the path text box.\nEnter / Ctrl-Enter (in the File Browser) to browse there;\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_CURRENT_NAME;Current name: +!FILEBROWSER_DARKFRAME;Dark frame +!FILEBROWSER_DELETEDLGMSGINCLPROC;Are you sure you want to delete the selected %1 files including a queue-processed version? +!FILEBROWSER_EXEC_CPB;Custom Profile Builder +!FILEBROWSER_EXTPROGMENU;Open with +!FILEBROWSER_FLATFIELD;Flat Field +!FILEBROWSER_MOVETODARKFDIR;Move to dark frames directory +!FILEBROWSER_MOVETOFLATFIELDDIR;Move to flat fields directory +!FILEBROWSER_NEW_NAME;New name: +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!FILEBROWSER_POPUPCOLORLABEL0;Label: None +!FILEBROWSER_POPUPCOLORLABEL1;Label: Red +!FILEBROWSER_POPUPCOLORLABEL2;Label: Yellow +!FILEBROWSER_POPUPCOLORLABEL3;Label: Green +!FILEBROWSER_POPUPCOLORLABEL4;Label: Blue +!FILEBROWSER_POPUPCOLORLABEL5;Label: Purple +!FILEBROWSER_POPUPCOLORLABEL;Color label +!FILEBROWSER_POPUPCOPYTO;Copy to... +!FILEBROWSER_POPUPFILEOPERATIONS;File Operations +!FILEBROWSER_POPUPMOVETO;Move to... +!FILEBROWSER_POPUPPROCESSFAST;Put to Queue (Fast export) +!FILEBROWSER_POPUPPROFILEOPERATIONS;Processing Profile Operations +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_POPUPREMOVESUBMENU;Remove +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!FILEBROWSER_QUERYHINT;Type a partial filename to search for.\nCtrl-F to focus the Find text box (in the File Browser).\nEnter to commence search. +!FILEBROWSER_QUERYLABEL; Find: +!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 +!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-` +!FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +!FILEBROWSER_USETEMPLATE;Use template: +!GENERAL_AFTER;After +!GENERAL_BEFORE;Before +!GENERAL_FILE;File +!GENERAL_HIGH_QUALITY;High Quality +!GENERAL_NONE;None +!GENERAL_UNCHANGED;(Unchanged) +!GENERAL_WARNING;Warning +!HISTOGRAM_BUTTON_BAR;RGB +!HISTOGRAM_BUTTON_B;B +!HISTOGRAM_BUTTON_G;G +!HISTOGRAM_BUTTON_L;L +!HISTOGRAM_BUTTON_RAW;Raw +!HISTOGRAM_BUTTON_R;R +!HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar\nClick right mouse button on image preview to freeze/unfreeze +!HISTOGRAM_TOOLTIP_FULL;Toggle full or scaled histogram +!HISTOGRAM_TOOLTIP_RAW;Show/Hide raw histogram +!HISTORY_MSG_82;Profile Changed +!HISTORY_MSG_83;High Quality Shadows/Highlights +!HISTORY_MSG_84;Perspective Correction +!HISTORY_MSG_85;Lens Correction Profile +!HISTORY_MSG_86;Wavelet Equalizer +!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 +!HISTORY_MSG_92;NR - Gamma +!HISTORY_MSG_93;Contrast by Detail Levels Value +!HISTORY_MSG_94;Contrast by Detail Levels +!HISTORY_MSG_95;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;RGB Saturation +!HISTORY_MSG_101;HSV EQ -- Hue +!HISTORY_MSG_102;HSV EQ -- Saturation +!HISTORY_MSG_103;HSV EQ -- Value +!HISTORY_MSG_104;HSV Equalizer +!HISTORY_MSG_105;Defringing +!HISTORY_MSG_106;Defringing Radius +!HISTORY_MSG_107;Defringing Threshold +!HISTORY_MSG_108;Highlight Compr. Threshold +!HISTORY_MSG_109;Resize Bounding Box +!HISTORY_MSG_110;Resizing applies o +!HISTORY_MSG_111;Avoid Color Shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;Red and Skin Tones Protection +!HISTORY_MSG_114;DCB Iterations +!HISTORY_MSG_115;False Color Iterations +!HISTORY_MSG_116;Enhanced DCB +!HISTORY_MSG_117;Red CA Correction +!HISTORY_MSG_118;Blue CA Correction +!HISTORY_MSG_119;Line Denoise +!HISTORY_MSG_120;Green Equil. Threshold +!HISTORY_MSG_121;Auto CA +!HISTORY_MSG_122;Auto Dark Frame +!HISTORY_MSG_123;Dark Frame File +!HISTORY_MSG_124;Linear Exp. Correction +!HISTORY_MSG_125;Exp. Correction Preserving HL +!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;Gamma +!HISTORY_MSG_134;Gamma Position +!HISTORY_MSG_135;Gamma Free +!HISTORY_MSG_136;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 Green Together +!HISTORY_MSG_142;Edges Sharpening - Iterations +!HISTORY_MSG_143;Edges Sharpening - Quantity +!HISTORY_MSG_144;Microcontrast - Quantity +!HISTORY_MSG_145;Microcontrast - Uniformity +!HISTORY_MSG_146;Edges Sharpening +!HISTORY_MSG_147;Edges Sharpening - 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;Vibrance - Pastel tones +!HISTORY_MSG_153;Vibrance - Saturated tones +!HISTORY_MSG_154;Vibrance - Protect skin tones +!HISTORY_MSG_155;Vibrance - Avoid color drift +!HISTORY_MSG_156;Vibrance - Link pastel and saturated tones +!HISTORY_MSG_157;Vibrance - Pastel/Saturated threshold +!HISTORY_MSG_158;Strength +!HISTORY_MSG_159;Edge Stopping +!HISTORY_MSG_160;Scale +!HISTORY_MSG_161;Reweighting Iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_163;RGB Curves - R +!HISTORY_MSG_164;RGB Curves - G +!HISTORY_MSG_165;RGB Curves - B +!HISTORY_MSG_166;Neutral Levels +!HISTORY_MSG_167;B&W Toning +!HISTORY_MSG_168;'Cc' curve +!HISTORY_MSG_169;'Ch' curve +!HISTORY_MSG_170;Vibrance - Curve +!MAIN_BUTTON_FULLSCREEN;Fullscreen +!MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Put current image to processing queue.\nShortcut: Ctrl+Q +!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_ERRORDURINGIMAGESAVING;Error during image saving +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue processed first. +!MAIN_MSG_NAVIGATOR;Navigator +!MAIN_MSG_PLACES;Places +!MAIN_TAB_COLOR_TOOLTIP;Shortcut: Alt-C +!MAIN_TAB_DETAIL_TOOLTIP;Shortcut: Alt-D +!MAIN_TAB_EXPORT; 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_TOGGLE_BEFORE_AFTER;B|A +!MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 8 +!MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 0 +!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_CHANNELMIXER;Channel mixer +!PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto fill +!PARTIALPASTE_DARKFRAMEAUTOSELECT;Dark Frame Auto Select +!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;FF Auto Select +!PARTIALPASTE_FLATFIELDBLURRADIUS;FF Blur Radius +!PARTIALPASTE_FLATFIELDBLURTYPE;FF Blur Type +!PARTIALPASTE_FLATFIELDFILE;Flat field (FF) File +!PARTIALPASTE_HLRECONSTRUCTION;Highlight reconstruction +!PARTIALPASTE_HLRECOVERYAMOUNT;Highlight recovery amount +!PARTIALPASTE_HLRECOVERYTHRESHOLD;Highlight recovery threshold +!PARTIALPASTE_HSVEQUALIZER;HSV Equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!PARTIALPASTE_LABCURVE;Lab adjustments +!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 Level +!PARTIALPASTE_RAWEXPOS_LINEAR;Raw white point linear corr. factor +!PARTIALPASTE_RAWEXPOS_PRESER;Raw white point HL preserving corr. (EV) +!PARTIALPASTE_RAWGROUP;Raw settings +!PARTIALPASTE_RAW_ALLENHANCE;Apply post demosaic artifact/noise reduction +!PARTIALPASTE_RAW_DCBENHANCE;Apply DCB enhancement step +!PARTIALPASTE_RAW_DCBITERATIONS;Number of DCB iterations +!PARTIALPASTE_RAW_DMETHOD;Demosaic Method +!PARTIALPASTE_RAW_FALSECOLOR;Demosaic False color suppression steps +!PARTIALPASTE_RGBCURVES;RGB curves +!PARTIALPASTE_SHARPENEDGE;Edges +!PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_VIBRANCE;Vibrance +!PARTIALPASTE_WAVELETEQUALIZER;Wavelet equalizer +!PREFERENCES_ADD;ADD +!PREFERENCES_AUTOMONPROFILE;Automatically use operating system's main monitor color profile +!PREFERENCES_BATCH_PROCESSING;Batch Processing +!PREFERENCES_BEHAVIOR;Behavior +!PREFERENCES_CUSTPROFBUILDHINT;Executable (or script) file called when a new initial processing profile should be generated for an image.\nReceives command line parameters to allow a rules-based processing profile generation:\n[raw/JPG path] [default processing profile path] [f-number] [exposure in secs] [focal length in mm] [ISO] [lens] [camera] +!PREFERENCES_CUSTPROFBUILDPATH;Executable path +!PREFERENCES_CUSTPROFBUILD;Custom Processing Profile Builder +!PREFERENCES_CUTOVERLAYBRUSH;Crop mask color/transparency +!PREFERENCES_DARKFRAMEFOUND;Found +!PREFERENCES_DARKFRAMESHOTS;shots +!PREFERENCES_DARKFRAMETEMPLATES;templates +!PREFERENCES_DARKFRAME;Dark Frame +!PREFERENCES_DATEFORMATFRAME;Date Format +!PREFERENCES_DIRDARKFRAMES;Dark frames directory +!PREFERENCES_EDITORLAYOUT;Editor Layout +!PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar (de-select for low res display) +!PREFERENCES_FLATFIELDFOUND;Found +!PREFERENCES_FLATFIELDSDIR;Flat Fields directory +!PREFERENCES_FLATFIELDSHOTS;shots +!PREFERENCES_FLATFIELDTEMPLATES;templates +!PREFERENCES_FLATFIELD;Flat Field +!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_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). On Windows use "SystemDefault", "SystemAsterisk" etc. for system sounds. +!PREFERENCES_SND_LNGEDITPROCDONE;Editor processing done +!PREFERENCES_SND_TRESHOLDSECS;after secs +!PREFERENCES_SQUAREDETAILWINDOW;Square detail window (faster) +!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_USESYSTEMTHEME; Use system theme +!PREFERENCES_WORKFLOW;Layout +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_SAVEPPASTE;Parameters to save +!PROGRESSBAR_BADPIXELS;Bad pixels... +!PROGRESSBAR_CACORRECTION;CA correction... +!PROGRESSBAR_DARKFRAME;Darkframe... +!PROGRESSBAR_GREENEQUIL;Green equilibrate... +!PROGRESSBAR_LINEDENOISE;Line Denoise... +!PROGRESSBAR_LOADINGTHUMBS;Loading thumbnails... +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing Profile Saved +!PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists +!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\nthe 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_CHROMATABERR_LABEL;Chromatic Aberration +!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_DETAIL_AMOUNT;Amount +!TP_DIRPYRDENOISE_CHROMA;Chrominance +!TP_DIRPYRDENOISE_GAMMA;Gamma +!TP_DIRPYRDENOISE_LABEL;Noise reduction +!TP_DIRPYRDENOISE_LUMA;Luminance +!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_EQUALIZER_CONTRAST_MINUS;Contrast- +!TP_EQUALIZER_CONTRAST_PLUS;Contrast+ +!TP_EQUALIZER_FINEST;finest +!TP_EQUALIZER_LABEL;Wavelet equalizer +!TP_EQUALIZER_LARGEST;coarsest +!TP_EQUALIZER_NEUTRAL;Neutral +!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 +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in auto levels operation +!TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Highlight recovery threshold +!TP_EXPOSURE_SATURATION;Saturation +!TP_EXPO_AFTER; After interpolation (before RGB conversion) +!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_HLREC_BLEND;Blend +!TP_HSVEQUALIZER_CHANNEL;HSV Channel +!TP_HSVEQUALIZER_HUE;H +!TP_HSVEQUALIZER_LABEL;HSV Equalizer +!TP_HSVEQUALIZER_NEUTRAL;Neutral +!TP_HSVEQUALIZER_SAT;S +!TP_HSVEQUALIZER_VAL;V +!TP_ICM_BLENDCMSMATRIX;Blend highlights with matrix +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover blown highlights when using LUT based ICC profiles +!TP_ICM_INPUTCAMERAICC;Auto-matched camera-specific color profile +!TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profile. These profiles are more precise than simpler matrix ones. Available for some 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_PREFERREDPROFILE;Preferred DCP profile +!TP_ICM_PREFERREDPROFILE_1;Daylight +!TP_ICM_PREFERREDPROFILE_2;Tungsten +!TP_ICM_PREFERREDPROFILE_3;Fluorescent +!TP_ICM_PREFERREDPROFILE_4;Flash +!TP_IMPULSEDENOISE_LABEL;Impulse Noise Reduction +!TP_IMPULSEDENOISE_THRESH;Impulse NR Threshold +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid Color Shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space\nand apply Munsell correction +!TP_LABCURVE_BRIGHTNESS;Brightness +!TP_LABCURVE_BWTONING;B&W Toning +!TP_LABCURVE_BWTONING_TIP;With B&W Toning option enabled, the Lab Chromaticity, Cc and Ch curves are not in effect.\nToning can be achieved using the a and b curves +!TP_LABCURVE_CHROMATICITY;Chromaticity +!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 the Chromaticity +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to the Hue +!TP_LABCURVE_LABEL;Lab Adjustments +!TP_LABCURVE_RSTPROTECTION;Red and Skin Tones Protection +!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;Use CA correction +!TP_LENSPROFILE_USEDIST;Use distortion correction +!TP_LENSPROFILE_USEVIGN;Use vignette correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset exposure controls to neutral values +!TP_PERSPECTIVE_HORIZONTAL;Horizontal +!TP_PERSPECTIVE_LABEL;Perspective +!TP_PERSPECTIVE_VERTICAL;Vertical +!TP_PREPROCESS_GREENEQUIL;Green equilibration +!TP_PREPROCESS_HOTDEADPIXFILT;Apply hot/dead pixel filter +!TP_PREPROCESS_HOTDEADPIXTHRESH;Hot/dead pixel detection threshold +!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 (leader) +!TP_RAWEXPOS_LINEAR;White Point: Linear corr. factor +!TP_RAWEXPOS_PRESER;White Point: HL preserving corr.(EV) +!TP_RAWEXPOS_TWOGREEN;Two greens together +!TP_RAW_ALLENHANCE;Apply post demosaic artifact/noise reduction +!TP_RAW_DCBENHANCE;Apply DCB enhancement step +!TP_RAW_DCBITERATIONS;Number of DCB iterations +!TP_RAW_LABEL;Demosaicing +!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_RED;R +!TP_SHARPENEDGE_AMOUNT;Quantity +!TP_SHARPENEDGE_LABEL;Edges +!TP_SHARPENEDGE_PASSES;Iterations +!TP_SHARPENEDGE_THREE;Luminance only +!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 the Hue +!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_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 +!ZOOMPANEL_100;(100%) +!ZOOMPANEL_NEWCROPWINDOW;Open (new) detail window +!ZOOMPANEL_ZOOM100;Zoom to 100% 1 +!ZOOMPANEL_ZOOMFITSCREEN;Fit to screen F +!ZOOMPANEL_ZOOMIN;Zoom In + +!ZOOMPANEL_ZOOMOUT;Zoom Out - diff --git a/rtdata/languages/Francais b/rtdata/languages/Francais new file mode 100644 index 000000000..2aeb2d8f5 --- /dev/null +++ b/rtdata/languages/Francais @@ -0,0 +1,1207 @@ +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 +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_DIALOGLABEL;Filtre EXIF +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;Forcer la réduction du bruit chromatique +EXPORT_BYPASS_DEFRINGE;Forcer l'aberration chromatique +EXPORT_BYPASS_DIRPYRDENOISE;Forcer la réduction du bruit +EXPORT_BYPASS_DIRPYREQUALIZER;Forcer le contraste par niveaux de détail +EXPORT_BYPASS_LUMADENOISE;Forcer la réduction du bruit de luminance +EXPORT_BYPASS_RAW_ALL_ENHANCE;Forcer l'application de la réduction de bruit/artefact post-dématriçage +EXPORT_BYPASS_RAW_CA;Forcer la correction d'aberration chromatique [raw] +EXPORT_BYPASS_RAW_CCSTEPS;Forcer la suppression des fausses couleurs [raw] +EXPORT_BYPASS_RAW_DCB_ENHANCE;Forcer l'application de la phase d'amélioration de DCB [raw] +EXPORT_BYPASS_RAW_DCB_ITERATIONS;Forcer le nombre d'itération de DCB [raw] +EXPORT_BYPASS_RAW_DF;Forcer la Trame Noire [raw] +EXPORT_BYPASS_RAW_FF;Forcer le Champ Uniforme [raw] +EXPORT_BYPASS_RAW_GREENTHRESH;Forcer l'équilibrage du vert [raw] +EXPORT_BYPASS_RAW_LINENOISE;Forcer le filtre de bruit de ligne [raw] +EXPORT_BYPASS_SHARPENEDGE;Forcer netteté des bords +EXPORT_BYPASS_SHARPENING;Forcer la netteté +EXPORT_BYPASS_SHARPENMICRO;Forcer netteté des microcontrastes +EXPORT_BYPASS_SH_HQ;Forcer Ombres/Hautes lumières (haute qualité) +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 pour 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_ARRANGEMENTHINT;Permuter entre l'alignement vertical/horizontal des vignettes +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 (Ctrl-o place le focus,Ctrl-Entrée pour naviguer dans le Navigateur de Fichier) +FILEBROWSER_CACHECLEARFROMFULL;Supprimer du cache (complet) +FILEBROWSER_CACHECLEARFROMPARTIAL;Supprimer du cache (partiel) +FILEBROWSER_CACHE;Cache +FILEBROWSER_CLEARPROFILE;Remettre le profil à zéro +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_EXIFFILTERAPPLYHINT;Activer/désactiver les filtres EXIF dans le navigateur de fichier +FILEBROWSER_EXIFFILTERAPPLY;Appliquer +FILEBROWSER_EXIFFILTERLABEL;Filtre EXIF +FILEBROWSER_EXIFFILTERSETTINGSHINT;Change les réglages du filtre EXIF +FILEBROWSER_EXIFFILTERSETTINGS;Réglages +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 Trame Noire +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;Abandonner la file de traitement +FILEBROWSER_POPUPCOLORLABEL0;Label: Aucun +FILEBROWSER_POPUPCOLORLABEL1;Label: Rouge +FILEBROWSER_POPUPCOLORLABEL2;Label: Jaune +FILEBROWSER_POPUPCOLORLABEL3;Label: Vert +FILEBROWSER_POPUPCOLORLABEL4;Label: Bleu +FILEBROWSER_POPUPCOLORLABEL5;Label: Violet +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_POPUPRANK1;1 étoile +FILEBROWSER_POPUPRANK2;2 étoiles +FILEBROWSER_POPUPRANK3;3 étoiles +FILEBROWSER_POPUPRANK4;4 étoiles +FILEBROWSER_POPUPRANK5;5 étoiles +FILEBROWSER_POPUPRANK;Étoiles +FILEBROWSER_POPUPREMOVEINCLPROC;Supprimer (y compris les sorties de la file de traitement) +FILEBROWSER_POPUPREMOVESUBMENU;Retirer +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_PROCESSINGSETTINGSHINT;Règle le format de fichier et le dossier de sortie +FILEBROWSER_PROCESSINGSETTINGS;Réglages +FILEBROWSER_QUERYBUTTONHINT;Effacer la recherche +FILEBROWSER_QUERYHINT;Taper la partie du nom du fichier à chercher. \nCtrl-f Place le curseur dans le champ de saisie;\nEntrée pour lancer la recherche +FILEBROWSER_QUERYLABEL;Chercher: +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 Alt-1 +FILEBROWSER_SHOWCOLORLABEL2HINT;Afficher les images avec un label Jaune Alt-2 +FILEBROWSER_SHOWCOLORLABEL3HINT;Afficher les images avec un label Vert Alt-3 +FILEBROWSER_SHOWCOLORLABEL4HINT;Afficher les images avec un label Bleu Alt-4 +FILEBROWSER_SHOWCOLORLABEL5HINT;Afficher les images avec un label Pourpre Alt-5 +FILEBROWSER_SHOWDIRHINT;Voir toutes les images du dossier D +FILEBROWSER_SHOWEDITEDHINT;Afficher les images éditées 7 +FILEBROWSER_SHOWEDITEDNOTHINT;Afficher les images non éditées 6 +FILEBROWSER_SHOWEXIFINFO;Montrer les infos EXIF i +FILEBROWSER_SHOWQUEUEHINT;Voir le contenu de la file de traitement +FILEBROWSER_SHOWRANK1HINT;Voir les images 1 étoile 1 +FILEBROWSER_SHOWRANK2HINT;Voir les images 2 étoiles 2 +FILEBROWSER_SHOWRANK3HINT;Voir les images 3 étoiles 3 +FILEBROWSER_SHOWRANK4HINT;Voir les images 4 étoiles 4 +FILEBROWSER_SHOWRANK5HINT;Voir les images 5 étoiles 5 +FILEBROWSER_SHOWRECENTLYSAVEDHINT;Afficher les images sauvegardées récemment Alt-7 +FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT; Afficher les images non sauvegardées récemment Alt-6 +FILEBROWSER_SHOWTRASHHINT;Voir le contenu de la corbeille T +FILEBROWSER_SHOWUNCOLORHINT;Afficher les images sans label de couleur Alt-` +FILEBROWSER_SHOWUNRANKHINT;Voir les images sans étoile ` +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_USETEMPLATE;Utiliser le modèle: +FILEBROWSER_ZOOMINHINT;Augmenter la taille des vignettes + +FILEBROWSER_ZOOMOUTHINT;Diminuer la taille des vignettes - +GENERAL_ABOUT;À propos +GENERAL_AFTER;Après +GENERAL_BEFORE;Avant +GENERAL_CANCEL;Annuler +GENERAL_DISABLED;Désactivé +GENERAL_DISABLE;Désactiver +GENERAL_ENABLED;Activé +GENERAL_ENABLE;Activer +GENERAL_FILE;Fichier +GENERAL_HIGH_QUALITY;Qualité élevée +GENERAL_LANDSCAPE;Paysage +GENERAL_LOAD;Charger +GENERAL_NA;indisponible +GENERAL_NONE;Aucun +GENERAL_NO;Non +GENERAL_OK;OK +GENERAL_PORTRAIT;Portrait +GENERAL_SAVE;Enregistrer +GENERAL_UNCHANGED;(Inchangé) +GENERAL_WARNING;Attention +GENERAL_YES;Oui +HISTOGRAM_BUTTON_BAR;RVB +HISTOGRAM_BUTTON_B;B +HISTOGRAM_BUTTON_G;V +HISTOGRAM_BUTTON_L;L +HISTOGRAM_BUTTON_RAW;RAW +HISTOGRAM_BUTTON_R;R +HISTOGRAM_LABEL;Histogramme +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_FULL;Basculer la vue de l'histogramme : complet / zoomé +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;Exposition auto +HISTORY_MSG_13;Rognage de l'exposition +HISTORY_MSG_14;Luminance - Luminosité +HISTORY_MSG_15;Luminance - 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é - Rayon +HISTORY_MSG_22;Netteté - Quantité +HISTORY_MSG_23;Netteté - Seuil +HISTORY_MSG_24;Netteté - Améliorer seulement les bords +HISTORY_MSG_25;Netteté - Amélio. bords - Rayon +HISTORY_MSG_26;Netteté - Amélio. bords - Tolérance +HISTORY_MSG_27;Netteté - Contrôle du halo +HISTORY_MSG_28;Netteté - 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;Température de couleur +HISTORY_MSG_40;Teinte de balance des blancs +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;Débruitage Chrom. - Sensible aux bords +HISTORY_MSG_50;Outil Ombres/Hautes lumières +HISTORY_MSG_51;Accentuation des hautes lumières +HISTORY_MSG_52;Accentuation des ombres +HISTORY_MSG_53;Amplitude tonale des hautes lumières +HISTORY_MSG_54;Amplitude tonale des ombres +HISTORY_MSG_55;Contraste Local +HISTORY_MSG_56;Ombres/Hautes lumières - 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 de la Photo +HISTORY_MSG_65;Aberration chromatique +HISTORY_MSG_66;Reconst. HL +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;Correction du vignettage +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 activé +HISTORY_MSG_82;Changement de profil +HISTORY_MSG_83;Ombres/Hautes lumières haute qualité +HISTORY_MSG_84;Correction de la perspective +HISTORY_MSG_85;Coefficients d'ondelette +HISTORY_MSG_86;Égaliseur d'ondelette +HISTORY_MSG_87;Réduction du bruit d'impulsion +HISTORY_MSG_88;Seuil de réduction de bruit +HISTORY_MSG_89;Réd. du bruit +HISTORY_MSG_90;Réd. de bruit Luminance +HISTORY_MSG_91;Réd. de bruit Chrominance +HISTORY_MSG_92;Réd. de bruit Gamma +HISTORY_MSG_93;Param. de contraste +HISTORY_MSG_94;Contraste par niveau de détail +HISTORY_MSG_95;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;Aberration chromatique +HISTORY_MSG_106;A.C. - Rayon +HISTORY_MSG_107;A.C. - 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;Éviter les dérives de teinte +HISTORY_MSG_112;--inutilisé-- +HISTORY_MSG_113;Protection des tons rouges et chair +HISTORY_MSG_114;Nbr d'itération DCB +HISTORY_MSG_115;Nbr d'itération des fausses couleurs +HISTORY_MSG_116;DCB amélioré +HISTORY_MSG_117;A.C. - Rouge +HISTORY_MSG_118;A.C. - Bleu +HISTORY_MSG_119;Filtre de bruit de ligne +HISTORY_MSG_120;Équilibrage du vert +HISTORY_MSG_121;Corr. auto. de l'aberr. chromatique +HISTORY_MSG_122;Trame Noire automatique +HISTORY_MSG_123;Champ Uniforme automatique +HISTORY_MSG_124;Correct. d'expo linéaire +HISTORY_MSG_125;Correct. d'expo préservant les HL +HISTORY_MSG_126;Champ Uniforme - Fichier +HISTORY_MSG_127;Champ Uniforme - Auto sélection +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 +HISTORY_MSG_134;Gamma - Position +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;Netteté des bords - itérations +HISTORY_MSG_143;Netteté des bords - quantité +HISTORY_MSG_144;Microcontraste - quantité +HISTORY_MSG_145;Microcontraste - uniformité +HISTORY_MSG_146;Netteté des bords +HISTORY_MSG_147;Netteté des 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;Vibrance - Tons pastels +HISTORY_MSG_153;Vibrance - Tons saturés +HISTORY_MSG_154;Vibrance - Protéger les tons chairs +HISTORY_MSG_155;Vibrance - Éviter les dérives de teinte +HISTORY_MSG_156;Vibrance - Lier Pastels et Saturés +HISTORY_MSG_157;Vibrance - Seuil entre Pastels/Saturés +HISTORY_MSG_158;Force +HISTORY_MSG_159;Arrêt des bords +HISTORY_MSG_160;Échelle +HISTORY_MSG_161;Itérations de la pondération +HISTORY_MSG_162;Compression tonale +HISTORY_MSG_163;Courbes RVB - R +HISTORY_MSG_164;Courbes RVB - V +HISTORY_MSG_165;Courbes RVB - B +HISTORY_MSG_166;Niveaux neutre +HISTORY_MSG_167;Mode N&B colorisable +HISTORY_MSG_168;Courbe 'CC' +HISTORY_MSG_169;Courbe 'CT' +HISTORY_MSG_170;Vibrance - courbe +HISTORY_MSG_171;Courbe 'LC' +HISTORY_MSG_172;Restreindre 'LC' aux tons rouge et peau +HISTORY_NEWSNAPSHOTAS;Sous... +HISTORY_NEWSNAPSHOT;Ajouter +HISTORY_NEWSSDIALOGLABEL;Label de la capture: +HISTORY_NEWSSDIALOGTITLE;Ajouter une nouvelle capture +HISTORY_SETTO;Réglé à +HISTORY_SNAPSHOTS;Captures +HISTORY_SNAPSHOT;Capture +ICMPANEL_FILEDLGFILTERANY;Tous les fichiers +ICMPANEL_FILEDLGFILTERICM;Fichiers de profil ICC +ICMPANEL_GAMMABEFOREINPUT;Appliquer le Gamma du profil +ICMPANEL_INPUTCAMERA;Celui de l'appareil photo +ICMPANEL_INPUTCUSTOM;Personnel +ICMPANEL_INPUTDLGLABEL;Choix du profil ICC d'entrée... +ICMPANEL_INPUTEMBEDDED;Utiliser celui inclus, si possible +ICMPANEL_INPUTPROFILE;Profil d'entrée +ICMPANEL_NOICM;Pas d'ICM: sortie sRGB +ICMPANEL_OUTPUTDLGLABEL;Choix du profil ICC de sortie... +ICMPANEL_OUTPUTPROFILE;Profil de sortie +ICMPANEL_SAVEREFERENCE;Utiliser l'image comme profil de référence +ICMPANEL_WORKINGPROFILE;Profil de travail +IMAGEAREA_DETAILVIEW;Vue de détail +IPTCPANEL_AUTHORHINT;Nom du créateur de l'objet, p.ex. le rédacteur, le photographe ou le graphiste (By-line). +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_EXIT;Sortie +MAIN_BUTTON_FULLSCREEN;Plein écran +MAIN_BUTTON_PREFERENCES;Préférences +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Ajouter l'image courante à la file de traitement Ctrl+Q +MAIN_BUTTON_QUEUE;Envoyer dans la file +MAIN_BUTTON_SAVE_TOOLTIP;Enregistrer l'image courante Ctrl+S +MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Éditer l'image courante dans l'éditeur externe Ctrl+E +MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Afficher/Cacher les 2 panneaux latéraux m +MAIN_BUTTON_UNFULLSCREEN;Quitter le plein écran +MAIN_FRAME_BATCHQUEUE;File d'attente +MAIN_FRAME_BATCHQUEUE_TOOLTIP; File de traitement Ctrl-F3 +MAIN_FRAME_EDITOR;Éditeur +MAIN_FRAME_EDITOR_TOOLTIP; Éditeur Ctrl-F4 +MAIN_FRAME_FILEBROWSER;Navigateur de fichiers +MAIN_FRAME_FILEBROWSER_TOOLTIP; Navigateur de fichiers 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_ERRORDURINGIMAGESAVING;Erreur pendant la sauvegarde de l'image +MAIN_MSG_EXITJOBSINQUEUEINFO;Les images non traitées seront perdues en quittant l'application +MAIN_MSG_EXITJOBSINQUEUEQUEST;Êtes-vous sûr de vouloir quitter? Il reste dans la file des images en attente de traitement. +MAIN_MSG_IMAGEUNPROCESSED;Cette commande nécessite que toutes les images sélectionnées aient été préalablement traité. +MAIN_MSG_JOBSINQUEUE;travail(aux) en file d'attente +MAIN_MSG_NAVIGATOR;Navigateur +MAIN_MSG_PLACES;Emplacement +MAIN_MSG_QOVERWRITE;Voulez-vous l'écraser? +MAIN_TAB_BASIC;Basique +MAIN_TAB_COLOR;Couleur +MAIN_TAB_COLOR_TOOLTIP;Alt-c +MAIN_TAB_DETAIL;Détail +MAIN_TAB_DETAIL_TOOLTIP;Alt-d +MAIN_TAB_DEVELOP; Développer +MAIN_TAB_EXIF;EXIF +MAIN_TAB_EXPORT; Exporter +MAIN_TAB_EXPOSURE;Exposition +MAIN_TAB_EXPOSURE_TOOLTIP;Alt-e +MAIN_TAB_FILTER; Filtrer +MAIN_TAB_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Métadonnées +MAIN_TAB_METADATA_TOOLTIP;Alt-m +MAIN_TAB_RAW;RAW +MAIN_TAB_RAW_TOOLTIP;Alt-r +MAIN_TAB_TAGGING;Étiquetter +MAIN_TAB_TRANSFORM;Transformation +MAIN_TAB_TRANSFORM_TOOLTIP;Alt-t +MAIN_TOGGLE_BEFORE_AFTER;Av|Ap +MAIN_TOOLTIP_BACKCOLOR0;Couleur de fond de l'aperçu: Selon le thème\nRaccourci : 8 +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: 0 +MAIN_TOOLTIP_BEFOREAFTERLOCK;Vérouille / déverouille la vue Avant\n\nVérouille: garde la vue Avant inchangée - \nutile pour évaluer l'effet cumultaif 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_HIDEFP;Montrer/cacher le panneau inférieur (navigateur de dossiers et de fichiers) F +MAIN_TOOLTIP_HIDEHP;Montrer/cacher le panneau gauche (incluant l'historique) H +MAIN_TOOLTIP_INDCLIPPEDH;Indication hautes lumières hors domaine +MAIN_TOOLTIP_INDCLIPPEDS;Indication ombres hors domaine +MAIN_TOOLTIP_PREFERENCES;Régler les préférences +MAIN_TOOLTIP_PREVIEWB;Affichage du canal Bleu +MAIN_TOOLTIP_PREVIEWFOCUSMASK;Affichage du Masque du focus (beta) 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 +MAIN_TOOLTIP_PREVIEWL;Affichage de la Luminosité\n0.299*R + 0.587*V + 0.114*B +MAIN_TOOLTIP_PREVIEWR;Affichage du canal Rouge +MAIN_TOOLTIP_QINFO;Montrer les infos EXIF I +MAIN_TOOLTIP_SAVEAS;Enregistrer l'image dans un dossier de son choix +MAIN_TOOLTIP_SAVE;Enregistrer l'image dans le dossier par défaut +MAIN_TOOLTIP_SHOWHIDELP1;Montrer/Cacher le panneau gauche H +MAIN_TOOLTIP_SHOWHIDERP1;Afficher/Cacher le panneau droit Alt-l +MAIN_TOOLTIP_SHOWHIDETP1;Afficher/Cacher le panneau supérieur Shift-l +MAIN_TOOLTIP_THRESHOLD;Seuil +MAIN_TOOLTIP_TOGGLE;Comparaison avant/après 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_CHANNELMIXER;Mixage des canaux +PARTIALPASTE_COARSETRANS;Rotation de 90° / symétrisation +PARTIALPASTE_COLORBOOST;Rehaussement couleur +PARTIALPASTE_COLORDENOISE;Réduction du bruit chromatique +PARTIALPASTE_COLORGROUP;Réglages couleurs +PARTIALPASTE_COLORMIXER;Mixage couleur +PARTIALPASTE_COLORSHIFT;Décalage couleur +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_HLRECONSTRUCTION;Reconstruction des hautes lumières +PARTIALPASTE_HLRECOVERYAMOUNT;Quantité de récup. des hautes lumières +PARTIALPASTE_HLRECOVERYTHRESHOLD;Seuil de récup. hautes lumières +PARTIALPASTE_HLRECOVERY;Récupération des hautes lumières +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_LUMADENOISE;Réduction du bruit de luminance +PARTIALPASTE_LUMINANCEGROUP;Réglages de la luminance +PARTIALPASTE_METAICMGROUP;Réglages des Métadonnées/ICM +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;Niveau de noir +PARTIALPASTE_RAWEXPOS_LINEAR;Facteur de corr. d'expos. linéaire +PARTIALPASTE_RAWEXPOS_PRESER;Corr. d'expos. préservant les HL +PARTIALPASTE_RAWGROUP;Réglages RAW +PARTIALPASTE_RAW_ALLENHANCE;Applique la réduction de bruit/artefact post-dématriçage +PARTIALPASTE_RAW_DCBENHANCE;Appliquer la phase d'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_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_WAVELETEQUALIZER;Égaliseur d'ondelette +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_BEHAVIOR;Comportement +PREFERENCES_BLINKCLIPPED;Faire clignoter les zones hors domaine +PREFERENCES_CACHECLEARALL;Tout nettoyer +PREFERENCES_CACHECLEARPROFILES;Nettoyer les profils +PREFERENCES_CACHECLEARTHUMBS;Nettoyer les vignettes +PREFERENCES_CACHEFORMAT1;Propriétaire (plus rapide et de meilleure qualité) +PREFERENCES_CACHEFORMAT2;JPEG (moins volumineux sur le disque) +PREFERENCES_CACHEMAXENTRIES;Nombre maximal d'éléments dans le Cache +PREFERENCES_CACHEOPTS;Options du Cache +PREFERENCES_CACHESTRAT1;Optimiser la vitesse au détriment de la consommation mémoire +PREFERENCES_CACHESTRAT2;Optimiser la consommation mémoire au détriment de la vitesse +PREFERENCES_CACHESTRAT;Stratégie de gestion du Cache +PREFERENCES_CACHETHUMBFORM;Format des vignettes du Cache +PREFERENCES_CACHETHUMBHEIGHT;Hauteur maximale des vignettes +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.\nParamètres de ligne de commande pour permettre la génération d'un .pp3 basé sur des règles:\n[Chemin vers le fichier RAW/JPG] [Chemin vers le profil par défault] [ouverture f] [tps d'exposition en seconde] [longueur focale en mm] [ISO] [Objectif] [Appareil photo] +PREFERENCES_CUSTPROFBUILDPATH;Chemin de l'exécutable +PREFERENCES_CUSTPROFBUILD;Constructeur de profil d'image personnalisé +PREFERENCES_CUTOVERLAYBRUSH;Masque de recadrage +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_DEMOSAICINGALGO;Algorithme de dématriçage +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_FLATFIELDAUTOSELECT;Sélection auto. du Champ Uniforme +PREFERENCES_FLATFIELDBLURRADIUS;Rayon de floutage du Champ Uniforme +PREFERENCES_FLATFIELDBLURTYPE;Type de floutage du Champ Uniforme +PREFERENCES_FLATFIELDFILE;Fichier de Champ Uniforme +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_FORIMAGE;Pour les fichiers images +PREFERENCES_FORRAW;Pour les fichiers RAW +PREFERENCES_GIMPPATH;Dossier d'intallation de GIMP +PREFERENCES_GTKTHEME;GTK par défaut +PREFERENCES_HINT;Conseil +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_LIVETHUMBNAILS;Vignettes "Live" (plus lent) +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_OUTDIRHINT;Vous pouvez utiliser les paramètres de chaîne formatées suivants:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nCes paramètres de chaînes formatées se réfèrent aux dossiers et sous-chemins du chemin du fichier RAW.\n\nPar exemple, si /home/tom/image/02-09-2006/dsc0012.nefa été ouvert, la signification des paramètres est:\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 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 'convertis' situé dans le dossier de l'originale, écrivez:\n%p1/convertis/%f\n\nSi vous voulez enregistrer l'image de sortie dans le dossier '/home/tom/convertis' en conservant le même sous-dossier de dates, écrivez:\n%p2/convertis/%d1/%f +PREFERENCES_OUTDIRTEMPLATEHINT;Vous pouvez utiliser les paramètres de chaîne formatées suivants:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nCes paramètres de chaînes formatées se réfèrent aux dossiers et sous-chemins du chemin du fichier RAW.\n\nPar exemple, si /home/tom/image/02-09-2006/dsc0012.nefa été ouvert, la signification des paramètres est:\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 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 'convertis' situé dans le dossier de l'originale, écrivez:\n%p1/convertis/%f\n\nSi vous voulez enregistrer l'image de sortie dans le dossier '/home/tom/convertis' en conservant le même sous-dossier de dates, é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_SELECTFONT;Police de caractère +PREFERENCES_SELECTICCDIRDLG;Choix du dossier des profils ICC... +PREFERENCES_SELECTLANG;Choix de la langue +PREFERENCES_SELECTMONITORPROFDLG;Choix du profil ICC de l'affichage... +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_SHOWONLYRAW;Voir seulement les fichiers RAW +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_OUTPUT;Options de sortie +PREFERENCES_TAB_SOUND;Sons +PREFERENCES_THUMBSIZE;Tailles des vignettes +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_USESYSTEMTHEME;Utiliser le thème système +PREFERENCES_WORKFLOW;Habitudes de travail +PROFILEPANEL_COPYPPASTE;Paramètres à copier +PROFILEPANEL_FILEDLGFILTERANY;Tous les fichiers +PROFILEPANEL_FILEDLGFILTERPP;Profils de post-traitement +PROFILEPANEL_LABEL;Profils de post-traitement +PROFILEPANEL_LOADDLGLABEL;Charger les paramètres de post-traitement... +PROFILEPANEL_LOADPPASTE;Paramètres à charger +PROFILEPANEL_PASTEPPASTE;Paramètres à coller +PROFILEPANEL_PCUSTOM;Personnel +PROFILEPANEL_PFILE;Depuis le fichier +PROFILEPANEL_PLASTPHOTO;Photo précédente +PROFILEPANEL_PLASTSAVED;Dernière sauvegarde +PROFILEPANEL_PROFILE;Profil +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_BADPIXELS;Pixels chauds/morts... +PROGRESSBAR_CACORRECTION;Correction de l'aberr. chomatique... +PROGRESSBAR_DARKFRAME;Trame Noire... +PROGRESSBAR_DECODING;Décodage du fichier RAW... +PROGRESSBAR_DEMOSAICING;Dématriçage... +PROGRESSBAR_GREENEQUIL;Équilibrage du vert... +PROGRESSBAR_LINEDENOISE;Filtrage de bruit de ligne... +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_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... +PROGRESSDLG_LOADING;Chargement du fichier... +PROGRESSDLG_PROCESSING;Traitement de l'image... +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profil modifié dans le navigateur +PROGRESSDLG_SAVING;Enregistrement du fichier... +QINFO_FOCALLENGTH;Longueur focale +QINFO_ISO;ISO +QINFO_LENS;Objectif +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_JPEGQUAL;Qualité JPEG +SAVEDLG_JPGFILTER;Fichiers JPEG +SAVEDLG_PNGCOMPR;Compression PNG +SAVEDLG_PNGFILTER;Fichiers 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éinitiliser 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 C +TOOLBAR_TOOLTIP_HAND;Outil de navigation N +TOOLBAR_TOOLTIP_STRAIGHTEN;Sélection de la ligne d'horizon S +TOOLBAR_TOOLTIP_WB;Choix du point déterminant la balance des blancs W +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_DEGREE;degré: +TP_COARSETRAF_TOOLTIP_HFLIP;Symétriser / axe vertical +TP_COARSETRAF_TOOLTIP_ROTLEFT;Rotation vers la gauche +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotation vers la droite +TP_COARSETRAF_TOOLTIP_VFLIP;Symétriser / axe horizontal +TP_COLORBOOST_ACHANNEL;canal "a" +TP_COLORBOOST_AMOUNT;Quantité +TP_COLORBOOST_AVOIDCOLORCLIP;Éviter l'écrêtage couleur +TP_COLORBOOST_BCHANNEL;canal "b" +TP_COLORBOOST_CHANNEL;Canal +TP_COLORBOOST_CHSEPARATE;séparé +TP_COLORBOOST_ENABLESATLIMITER;Activer le limiteur de saturation +TP_COLORBOOST_LABEL;Rehaussement couleur +TP_COLORBOOST_SATLIMIT;Limite de saturation +TP_COLORDENOISE_EDGESENSITIVE;Sensible aux bords +TP_COLORDENOISE_EDGETOLERANCE;Tolérance des bords +TP_COLORDENOISE_LABEL;Réduction du bruit chromatique +TP_COLORDENOISE_RADIUS;Rayon +TP_COLORSHIFT_BLUEYELLOW;Bleu-Jaune +TP_COLORSHIFT_GREENMAGENTA;Vert-Magenta +TP_COLORSHIFT_LABEL;Décalage couleur +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_DETAIL_AMOUNT;Quantité +TP_DIRPYRDENOISE_CHROMA;Chrominance +TP_DIRPYRDENOISE_GAMMA;Gamma +TP_DIRPYRDENOISE_LABEL;Réduction du bruit +TP_DIRPYRDENOISE_LUMA;Luminance +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_EQUALIZER_CONTRAST_MINUS;Contraste- +TP_EQUALIZER_CONTRAST_PLUS;Contraste+ +TP_EQUALIZER_FINEST;les plus petites +TP_EQUALIZER_LABEL;Égaliseur d'ondelette +TP_EQUALIZER_LARGEST;les plus grandes +TP_EQUALIZER_NEUTRAL;Neutre +TP_EXPOSCORR_LABEL;Exposition +TP_EXPOSURE_AUTOLEVELS;Niveaux Auto +TP_EXPOSURE_AUTOLEVELS_TIP;Bascule l'usage de Niveaux automatiques afin de régler\nautomatiquement les valeurs basé sur l'analyse de l'image +TP_EXPOSURE_BLACKLEVEL;Noir +TP_EXPOSURE_BRIGHTNESS;Luminosité +TP_EXPOSURE_CLIP;Rognage +TP_EXPOSURE_CLIP_TIP;La fraction de pixels que l'outil Niveaux automatiques 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_WEIGHTEDSTD;Standard Pondéré +TP_EXPOSURE_TCMODE_STANDARD;Standard +TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Mixage Saturation et Valeur +TP_EXPO_AFTER; Après l'interpolation (avant la conversion RVB) +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_HLREC_BLEND;Blend (mélange) +TP_HLREC_CIELAB;Mélange CIELab +TP_HLREC_COLOR;Propagation de la couleur +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_NEUTRAL;Neutre +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_FILEDLGFILTERANY;Tous les fichiers +TP_ICM_FILEDLGFILTERICM;Fichiers de profil +TP_ICM_GAMMABEFOREINPUT;Appliquer le Gamma du profil +TP_ICM_INPUTCAMERAICC;Profil spécifique à l'APN\nsélectionné automatiquement +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 appareil 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 inclus dans le fichier RAW, les matrices de couleur simple fournis 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_OUTPUTDLGLABEL;Choix du profil ICC de sortie... +TP_ICM_OUTPUTPROFILE;Profil de sortie +TP_ICM_PREFERREDPROFILE;Profil DCP préféré +TP_ICM_PREFERREDPROFILE_1;Lumière du jour (ensoleillé) +TP_ICM_PREFERREDPROFILE_2;Tungstène +TP_ICM_PREFERREDPROFILE_3;Fluorescent +TP_ICM_PREFERREDPROFILE_4;Flash +TP_ICM_SAVEREFERENCE;Utiliser l'image comme profil de référence +TP_ICM_TONECURVE;Utiliser la courbe tonale du profil DCP +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_RSTPRO_TOOLTIP;Peut être tutilisé avec le curseur Chromaticité et la courbe CC. +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é, s'applique à toutes les teintes +TP_LABCURVE_BRIGHTNESS;Luminosité +TP_LABCURVE_BWTONING;Mode N&B colorisable +TP_LABCURVE_BWTONING_TIP;Avec le mode N&B colorisable activé, la Chromaticité, la courbe CC, CT et LC sont sans effet.\nLa colorisation peut être effctué en utilisant les courbes a et b. +TP_LABCURVE_CHROMATICITY;Chromaticité +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é +TP_LABCURVE_CURVEEDITOR_CH;CT +TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticité en fonction de la Teinte +TP_LABCURVE_CURVEEDITOR_LC;LC +TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminance en fonction de la Chromaticité +TP_LABCURVE_LABEL;Ajustements Lab +TP_LABCURVE_RSTPROTECTION;Protection des tons rouges et chair +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;Appliquer la correction de l'aberration chromatique +TP_LENSPROFILE_USEDIST;Appliquer la correction de la distortion +TP_LENSPROFILE_USEVIGN;Appliquer la correction du vignettage +TP_LUMADENOISE_EDGETOLERANCE;Tolérance des bords +TP_LUMADENOISE_LABEL;Réduction du bruit de luminance +TP_LUMADENOISE_RADIUS;Rayon +TP_NEUTRAL;Neutre +TP_NEUTRAL_TIP;Réinitialise les valeurs de l'exposition à des valeurs neutres +TP_PERSPECTIVE_HORIZONTAL;Horizontale +TP_PERSPECTIVE_LABEL;Perspective +TP_PERSPECTIVE_VERTICAL;Verticale +TP_PREPROCESS_GREENEQUIL;Équilibrage du vert +TP_PREPROCESS_HOTDEADPIXFILT;Filtrer les pixels chauds/morts +TP_PREPROCESS_HOTDEADPIXTHRESH;Seuil de détection des pixels 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;Facteur de corr. linéaire +TP_RAWEXPOS_PRESER;Corr. préservant les HL (EV) +TP_RAWEXPOS_TWOGREEN;Lier les 2 niveaux de Vert +TP_RAW_ALLENHANCE;Réduction de bruit/artefact post-dématriçage +TP_RAW_DCBENHANCE;Appliquer la phase d'amélioration de DCB +TP_RAW_DCBITERATIONS;Nombre d'itération de DCB +TP_RAW_DMETHOD;Méthode +TP_RAW_FALSECOLOR;Itérations pour la suppression\ndes fausses couleurs +TP_RAW_LABEL;Dématriçage +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_DOWNSCALEB;Diminuer (Meilleur) +TP_RESIZE_DOWNSCALEF;Diminuer (Plus rapide) +TP_RESIZE_FITBOX;Boîte englobante +TP_RESIZE_FULLIMAGE;L'image entière +TP_RESIZE_FULLSIZE;Dimensions finales de l'image: +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_RED;R +TP_ROTATE_DEGREE;Degré +TP_ROTATE_LABEL;Rotation +TP_ROTATE_SELECTLINE;Choisir la ligne d'horizon +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_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_USM;Masque flou +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 represente les tons pastel en bas et le tons saturés en haut.\nL'axe horizontal represente 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_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 +ZOOMBAR_DETAIL;Détail +ZOOMBAR_HUGE;Énorme +ZOOMBAR_LARGE;Large +ZOOMBAR_NORMAL;Normal +ZOOMBAR_PREVIEW;Prévisualiation +ZOOMBAR_SCALE;Échelle +ZOOMBAR_SMALL;Petit +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;Ouvrir une (nouvelle) vue détaillée +ZOOMPANEL_ZOOM100;Zoom à 100% 1 +ZOOMPANEL_ZOOMFITSCREEN;Ajuster à la fenêtre F +ZOOMPANEL_ZOOMIN;Zoom + +ZOOMPANEL_ZOOMOUT;Zoom - +#00 Français +#01 1.3.2008: Initial translation by Hombre diff --git a/rtdata/languages/Greek b/rtdata/languages/Greek new file mode 100644 index 000000000..a05e88a81 --- /dev/null +++ b/rtdata/languages/Greek @@ -0,0 +1,1207 @@ +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_DIALOGLABEL;Exif Filter +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_ARRANGEMENTHINT;Change between vertical/horizontal alignment of thumbnails +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_EXIFFILTERAPPLYHINT;Switch on/off exif filter of the file browser +FILEBROWSER_EXIFFILTERAPPLY;Apply +FILEBROWSER_EXIFFILTERLABEL;Exif Filter +FILEBROWSER_EXIFFILTERSETTINGSHINT;Change settings of the exif filter +FILEBROWSER_EXIFFILTERSETTINGS;Setup +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_POPUPRANK1;Rank 1 +FILEBROWSER_POPUPRANK2;Rank 2 +FILEBROWSER_POPUPRANK3;Rank 3 +FILEBROWSER_POPUPRANK4;Rank 4 +FILEBROWSER_POPUPRANK5;Rank 5 +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_PROCESSINGSETTINGSHINT;Set the file format and output directory +FILEBROWSER_PROCESSINGSETTINGS;Settings +FILEBROWSER_RENAMEDLGLABEL;Rename file +FILEBROWSER_RENAMEDLGMSG;Rename file "%1" to: +FILEBROWSER_SHOWDIRHINT;Show all images of the directory +FILEBROWSER_SHOWQUEUEHINT;Show content of the processing queue +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_LOAD;Φόρτωση +GENERAL_NA;μη διαθέσιμο +GENERAL_NO;Όχι +GENERAL_OK;Εντάξει +GENERAL_PORTRAIT;Πορτραίτο +GENERAL_SAVE;Αποθήκευση +GENERAL_YES;Ναί +HISTOGRAM_LABEL;Histogram +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_NEWSNAPSHOTAS;Ως... +HISTORY_NEWSNAPSHOT;Νέο στιγμιότυπο +HISTORY_NEWSSDIALOGLABEL;Όνομα στιγμιοτύπου: +HISTORY_NEWSSDIALOGTITLE;Προσθήκη νέου στιγμιοτύπου +HISTORY_SETTO;Ορισμός σε +HISTORY_SNAPSHOTS;Στιγμιότυπα +HISTORY_SNAPSHOT;Στιγμιότυπο +ICMPANEL_FILEDLGFILTERANY;Οποιοδήποτε αρχείο +ICMPANEL_FILEDLGFILTERICM;Αρχεία προφίλ ICC +ICMPANEL_GAMMABEFOREINPUT;Το προφίλ αλλάζει την gamma +ICMPANEL_INPUTCAMERA;Προεπιλογή φωτογραφικής μηχανής +ICMPANEL_INPUTCUSTOM;Προσαρμοσμένο +ICMPANEL_INPUTDLGLABEL;Επιλέξτε προφιλ ICC εισόδου... +ICMPANEL_INPUTEMBEDDED;Χρήση ενσωματωμένου, αν αυτό είναι δυνατό +ICMPANEL_INPUTPROFILE;Προφίλ εισαγωγής +ICMPANEL_NOICM;No ICM: sRGB output +ICMPANEL_OUTPUTDLGLABEL;Επιλέξτε προφιλ ICC εξόδου... +ICMPANEL_OUTPUTPROFILE;Προφίλ εξόδου +ICMPANEL_SAVEREFERENCE;Αποθήκευση εικόνας ως αναφορά για δημιουργία προφίλ. +ICMPANEL_WORKINGPROFILE;Παρόν προφίλ +IMAGEAREA_DETAILVIEW;Λεπτομερής προβολή +IPTCPANEL_AUTHORHINT;Όνομα του δημιουργού του αντικειμένου, π.χ. συγγραφέας, φωτογράφος ή γραφίστας (Ανα γραμμή). +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_EXIT;Exit +MAIN_BUTTON_PREFERENCES;Ρυθμίσεις +MAIN_BUTTON_QUEUE;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_EXITJOBSINQUEUEINFO;Unprocessed images in the queue will be lost on exit. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Are you sure you want to exit? There are unprocessed images waiting in the queue. +MAIN_MSG_JOBSINQUEUE;εργασία(ες) μέσα στην λίστα αναμονής +MAIN_MSG_QOVERWRITE;Θέλετε να το αντικαταστήσετε; +MAIN_TAB_BASIC;Βασικό +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_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;Μετατροπή +MAIN_TOOLTIP_HIDEFP;Προβολή/απόκρυψη του κάτω πλαισίου (τοποθεσίες και περιηγητής αρχείων, shortcut key: F) +MAIN_TOOLTIP_HIDEHP;Προβολή/απόκρυψη αριστερού πλαισίου (περιλαμβανομένου του ιστορικού, shortcut key: H) +MAIN_TOOLTIP_INDCLIPPEDH;Ένδειξη ψαλισμού φωτεινών σημείων +MAIN_TOOLTIP_INDCLIPPEDS;Ένδειξη ψαλισμού σκιών +MAIN_TOOLTIP_PREFERENCES;Ορισμός ρυθμίσεων +MAIN_TOOLTIP_QINFO;Γρήγορες πληροφορίες στην εικόνα +MAIN_TOOLTIP_SAVEAS;Αποθήκευση εικόνας σε ένα επιλεγμένο φάκελο +MAIN_TOOLTIP_SAVE;Αποθήκευση εικόνας στον προκαθορισμένο φάκελο +PARTIALPASTE_BASICGROUP;Basic settings +PARTIALPASTE_CACORRECTION;C/A correction +PARTIALPASTE_COARSETRANS;90 deg rotation / flipping +PARTIALPASTE_COLORBOOST;Color boost +PARTIALPASTE_COLORDENOISE;Color denoise +PARTIALPASTE_COLORGROUP;Color related settings +PARTIALPASTE_COLORMIXER;Color mixer +PARTIALPASTE_COLORSHIFT;Color shift +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_HLRECOVERY;Highlight recovery +PARTIALPASTE_ICMSETTINGS;ICM settings +PARTIALPASTE_IPTCINFO;IPTC info +PARTIALPASTE_LENSGROUP;Lens related settings +PARTIALPASTE_LUMACURVE;Luminance curve +PARTIALPASTE_LUMADENOISE;Luminance noise reduction +PARTIALPASTE_LUMINANCEGROUP;Luminance related settings +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_CACHESTRAT1;Prefer Speed to Low Memory Consumption +PREFERENCES_CACHESTRAT2;Prefer Low Memory Consumption to Speed +PREFERENCES_CACHESTRAT;Cache Strategy +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_DEMOSAICINGALGO;Αλγόριθμος απομωσαϊκοποίησης +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_HINT;Νύξη +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_LIVETHUMBNAILS;Live Thumbnails (slower) +PREFERENCES_MONITORICC;Προφίλ οθόνης +PREFERENCES_OUTDIRFOLDERHINT;Put the saved images to the seledted folder +PREFERENCES_OUTDIRFOLDER;Save to folder +PREFERENCES_OUTDIRHINT;Μπορείτε να χρησιμοποιήσετε τις ακόλουθες σειρές μορφοποίησης:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nΑυτές οι σειρές μορφοποίησης αναφέρονται στις τοποθεσίες και τις υπο-διαδρομές της τοποθεσίας του αρχείου raw.\n\nΓια παράδειγμα, αν το /home/tom/image/02-09-2006/dsc0012.nef ανοιχθεί, η σημασία των ακόλουθων σειρών μορφοποίησης είναι:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nΑν θέλεθτε να αποδηκεύσετε την εικόνα εξόδου μαζί με το πρωτότυπο, γράψτε:\n%p1/%f\n\nΑν θέλετε να αποθηκεύσετε την εικόνα εξόδου σε ένα φάκελο 'converted', μέσα στην τοποθεσία που βρίσκεται το πρωτότυπο, γράψτε:\n%p1/converted/%f\n\nΑν θέλετε να αποθηκεύσετε την εικόνα εξόδου σε στην τοποθεσία '/home/tom/converted' κρατώντας όμως την ίδια δομή υπο-τοποθεσιών ημερομηνίων, γράψτε:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATEHINT;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_SELECTICCDIRDLG;Επιλογή τοποθεσίας προφίλ ICC... +PREFERENCES_SELECTLANG;Επιλογή γλώσσας +PREFERENCES_SELECTMONITORPROFDLG;Επιλογή προφίλ ICC της οθόνης... +PREFERENCES_SELECTTHEME;Επιλογή θέματος +PREFERENCES_SHOWBASICEXIF;Προβολή βασικών στοιχείων Exif +PREFERENCES_SHOWDATETIME;Προβολή ημερομηνίας και ώρας +PREFERENCES_SHOWONLYRAW;Προβολή μόνο αρχείων RAW +PREFERENCES_SHTHRESHOLD;Κατώφλι ψαλιδίσματος σκιών +PREFERENCES_STARTUPIMDIR;Τοποθεσία εικόνων κατά την έναρξη +PREFERENCES_TAB_BROWSER;Περιήγηση αρχείου +PREFERENCES_TAB_COLORMGR;Διαχείριση χρώματος +PREFERENCES_TAB_GENERAL;Γενικά +PREFERENCES_TAB_IMPROC;Επεξεργασίας εικόνας +PREFERENCES_TAB_OUTPUT;Επιλογές παραγωγής +PREFERENCES_THUMBSIZE;Μέγεθος εικονιδίου +PROFILEPANEL_FILEDLGFILTERANY;Οποιοφήποτε αρχείο +PROFILEPANEL_FILEDLGFILTERPP;Προφίλ επεξεργασίας +PROFILEPANEL_LABEL;Προφίλ επεξεργασίας +PROFILEPANEL_LOADDLGLABEL;Φόρτωση παραμέτρων επεξεργασίας... +PROFILEPANEL_PCUSTOM;Προσαρμοσμένο +PROFILEPANEL_PFILE;Απο αρχείο +PROFILEPANEL_PLASTPHOTO;Τελευταία φωτογραφία +PROFILEPANEL_PLASTSAVED;Τελευταία αποθηκευμένη +PROFILEPANEL_PROFILE;Προφίλ +PROFILEPANEL_SAVEDLGLABEL;Αποθήκευση παραμέτρων επεξεργασίας... +PROFILEPANEL_TOOLTIPCOPY;Copy current profile to clipboard +PROFILEPANEL_TOOLTIPLOAD;Φόρτωση προφίλ απο αρχείο +PROFILEPANEL_TOOLTIPPASTE; Paste profile from clipboard +PROFILEPANEL_TOOLTIPSAVE;Αποθήκευση παρόντος προφίλ +PROGRESSBAR_DECODING;Αποκωδικοποίηση εικόνας... +PROGRESSBAR_DEMOSAICING;Demosaicing... +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_FOCALLENGTH;Εστιακή απόσταση +QINFO_ISO;ISO +QINFO_LENS;Lens +QINFO_NOEXIF;Στοιχεία Exif μη διαθέσιμα. +SAVEDLG_FILEFORMAT;Είδος αρχείου +SAVEDLG_JPEGQUAL;Ποιότητα JPEG +SAVEDLG_JPGFILTER;Αρχεία JPEG +SAVEDLG_PNGCOMPR;Συμπίεση PNG +SAVEDLG_PNGFILTER;Αρχεία 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_OUTPUTDLGLABEL;Επιλέξτε προφιλ ICC εξόδου... +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_LUMADENOISE_EDGETOLERANCE;Ανοχή ορίων +TP_LUMADENOISE_LABEL;Μείωση θορύβου φωτεινότητας +TP_LUMADENOISE_RADIUS;Ακτίνα +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_FULLSIZE;Πλήρες μέγεθος εικόνας: +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;Θερμοκρασία +ZOOMBAR_DETAIL;Λεπτομέρεια +ZOOMBAR_HUGE;Τεράστιο +ZOOMBAR_LARGE;Μεγάλο +ZOOMBAR_NORMAL;Κανονικό +ZOOMBAR_PREVIEW;Προεπισκόπηση +ZOOMBAR_SCALE;Κλίμακα +ZOOMBAR_SMALL;Μικρό + +#00 Greek +#01 14.05.2008: zeusalmighty + +!!!!!!!!!!!!!!!!!!!!!!!!! +! 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 +!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_SHARPENEDGE;Bypass Edge Sharpening +!EXPORT_BYPASS_SHARPENING;Bypass Sharpening +!EXPORT_BYPASS_SHARPENMICRO;Bypass Microcontrast +!EXPORT_BYPASS_SH_HQ;Bypass Shadow/Highlights (High Quality) +!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 the path text box.\nEnter / Ctrl-Enter (in the File Browser) to browse there;\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_CURRENT_NAME;Current name: +!FILEBROWSER_DARKFRAME;Dark frame +!FILEBROWSER_DELETEDLGMSGINCLPROC;Are you sure you want to delete the selected %1 files including a queue-processed version? +!FILEBROWSER_EXEC_CPB;Custom Profile Builder +!FILEBROWSER_EXTPROGMENU;Open with +!FILEBROWSER_FLATFIELD;Flat Field +!FILEBROWSER_MOVETODARKFDIR;Move to dark frames directory +!FILEBROWSER_MOVETOFLATFIELDDIR;Move to flat fields directory +!FILEBROWSER_NEW_NAME;New name: +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!FILEBROWSER_POPUPCOLORLABEL0;Label: None +!FILEBROWSER_POPUPCOLORLABEL1;Label: Red +!FILEBROWSER_POPUPCOLORLABEL2;Label: Yellow +!FILEBROWSER_POPUPCOLORLABEL3;Label: Green +!FILEBROWSER_POPUPCOLORLABEL4;Label: Blue +!FILEBROWSER_POPUPCOLORLABEL5;Label: Purple +!FILEBROWSER_POPUPCOLORLABEL;Color label +!FILEBROWSER_POPUPCOPYTO;Copy to... +!FILEBROWSER_POPUPFILEOPERATIONS;File Operations +!FILEBROWSER_POPUPMOVETO;Move to... +!FILEBROWSER_POPUPPROCESSFAST;Put to Queue (Fast export) +!FILEBROWSER_POPUPPROFILEOPERATIONS;Processing Profile Operations +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_POPUPREMOVESUBMENU;Remove +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!FILEBROWSER_QUERYHINT;Type a partial filename to search for.\nCtrl-F to focus the Find text box (in the File Browser).\nEnter to commence search. +!FILEBROWSER_QUERYLABEL; Find: +!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 +!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-` +!FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +!FILEBROWSER_USETEMPLATE;Use template: +!GENERAL_AFTER;After +!GENERAL_BEFORE;Before +!GENERAL_FILE;File +!GENERAL_HIGH_QUALITY;High Quality +!GENERAL_NONE;None +!GENERAL_UNCHANGED;(Unchanged) +!GENERAL_WARNING;Warning +!HISTOGRAM_BUTTON_BAR;RGB +!HISTOGRAM_BUTTON_B;B +!HISTOGRAM_BUTTON_G;G +!HISTOGRAM_BUTTON_L;L +!HISTOGRAM_BUTTON_RAW;Raw +!HISTOGRAM_BUTTON_R;R +!HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar\nClick right mouse button on image preview to freeze/unfreeze +!HISTOGRAM_TOOLTIP_FULL;Toggle full or scaled histogram +!HISTOGRAM_TOOLTIP_RAW;Show/Hide raw histogram +!HISTORY_MSG_82;Profile Changed +!HISTORY_MSG_83;High Quality Shadows/Highlights +!HISTORY_MSG_84;Perspective Correction +!HISTORY_MSG_85;Lens Correction Profile +!HISTORY_MSG_86;Wavelet Equalizer +!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 +!HISTORY_MSG_92;NR - Gamma +!HISTORY_MSG_93;Contrast by Detail Levels Value +!HISTORY_MSG_94;Contrast by Detail Levels +!HISTORY_MSG_95;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;RGB Saturation +!HISTORY_MSG_101;HSV EQ -- Hue +!HISTORY_MSG_102;HSV EQ -- Saturation +!HISTORY_MSG_103;HSV EQ -- Value +!HISTORY_MSG_104;HSV Equalizer +!HISTORY_MSG_105;Defringing +!HISTORY_MSG_106;Defringing Radius +!HISTORY_MSG_107;Defringing Threshold +!HISTORY_MSG_108;Highlight Compr. Threshold +!HISTORY_MSG_109;Resize Bounding Box +!HISTORY_MSG_110;Resizing applies o +!HISTORY_MSG_111;Avoid Color Shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;Red and Skin Tones Protection +!HISTORY_MSG_114;DCB Iterations +!HISTORY_MSG_115;False Color Iterations +!HISTORY_MSG_116;Enhanced DCB +!HISTORY_MSG_117;Red CA Correction +!HISTORY_MSG_118;Blue CA Correction +!HISTORY_MSG_119;Line Denoise +!HISTORY_MSG_120;Green Equil. Threshold +!HISTORY_MSG_121;Auto CA +!HISTORY_MSG_122;Auto Dark Frame +!HISTORY_MSG_123;Dark Frame File +!HISTORY_MSG_124;Linear Exp. Correction +!HISTORY_MSG_125;Exp. Correction Preserving HL +!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;Gamma +!HISTORY_MSG_134;Gamma Position +!HISTORY_MSG_135;Gamma Free +!HISTORY_MSG_136;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 Green Together +!HISTORY_MSG_142;Edges Sharpening - Iterations +!HISTORY_MSG_143;Edges Sharpening - Quantity +!HISTORY_MSG_144;Microcontrast - Quantity +!HISTORY_MSG_145;Microcontrast - Uniformity +!HISTORY_MSG_146;Edges Sharpening +!HISTORY_MSG_147;Edges Sharpening - 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;Vibrance - Pastel tones +!HISTORY_MSG_153;Vibrance - Saturated tones +!HISTORY_MSG_154;Vibrance - Protect skin tones +!HISTORY_MSG_155;Vibrance - Avoid color drift +!HISTORY_MSG_156;Vibrance - Link pastel and saturated tones +!HISTORY_MSG_157;Vibrance - Pastel/Saturated threshold +!HISTORY_MSG_158;Strength +!HISTORY_MSG_159;Edge Stopping +!HISTORY_MSG_160;Scale +!HISTORY_MSG_161;Reweighting Iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_163;RGB Curves - R +!HISTORY_MSG_164;RGB Curves - G +!HISTORY_MSG_165;RGB Curves - B +!HISTORY_MSG_166;Neutral Levels +!HISTORY_MSG_167;B&W Toning +!HISTORY_MSG_168;'Cc' curve +!HISTORY_MSG_169;'Ch' curve +!HISTORY_MSG_170;Vibrance - Curve +!MAIN_BUTTON_FULLSCREEN;Fullscreen +!MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Put current image to processing queue.\nShortcut: Ctrl+Q +!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_ERRORDURINGIMAGESAVING;Error during image saving +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue processed first. +!MAIN_MSG_NAVIGATOR;Navigator +!MAIN_MSG_PLACES;Places +!MAIN_TAB_COLOR_TOOLTIP;Shortcut: Alt-C +!MAIN_TAB_DETAIL_TOOLTIP;Shortcut: Alt-D +!MAIN_TAB_EXPORT; 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_TOGGLE_BEFORE_AFTER;B|A +!MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 8 +!MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 0 +!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_CHANNELMIXER;Channel mixer +!PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto fill +!PARTIALPASTE_DARKFRAMEAUTOSELECT;Dark Frame Auto Select +!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;FF Auto Select +!PARTIALPASTE_FLATFIELDBLURRADIUS;FF Blur Radius +!PARTIALPASTE_FLATFIELDBLURTYPE;FF Blur Type +!PARTIALPASTE_FLATFIELDFILE;Flat field (FF) File +!PARTIALPASTE_HLRECONSTRUCTION;Highlight reconstruction +!PARTIALPASTE_HLRECOVERYAMOUNT;Highlight recovery amount +!PARTIALPASTE_HLRECOVERYTHRESHOLD;Highlight recovery threshold +!PARTIALPASTE_HSVEQUALIZER;HSV Equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!PARTIALPASTE_LABCURVE;Lab adjustments +!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 Level +!PARTIALPASTE_RAWEXPOS_LINEAR;Raw white point linear corr. factor +!PARTIALPASTE_RAWEXPOS_PRESER;Raw white point HL preserving corr. (EV) +!PARTIALPASTE_RAWGROUP;Raw settings +!PARTIALPASTE_RAW_ALLENHANCE;Apply post demosaic artifact/noise reduction +!PARTIALPASTE_RAW_DCBENHANCE;Apply DCB enhancement step +!PARTIALPASTE_RAW_DCBITERATIONS;Number of DCB iterations +!PARTIALPASTE_RAW_DMETHOD;Demosaic Method +!PARTIALPASTE_RAW_FALSECOLOR;Demosaic False color suppression steps +!PARTIALPASTE_RGBCURVES;RGB curves +!PARTIALPASTE_SHARPENEDGE;Edges +!PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_VIBRANCE;Vibrance +!PARTIALPASTE_WAVELETEQUALIZER;Wavelet equalizer +!PREFERENCES_ADD;ADD +!PREFERENCES_AUTOMONPROFILE;Automatically use operating system's main monitor color profile +!PREFERENCES_BATCH_PROCESSING;Batch Processing +!PREFERENCES_BEHAVIOR;Behavior +!PREFERENCES_CUSTPROFBUILDHINT;Executable (or script) file called when a new initial processing profile should be generated for an image.\nReceives command line parameters to allow a rules-based processing profile generation:\n[raw/JPG path] [default processing profile path] [f-number] [exposure in secs] [focal length in mm] [ISO] [lens] [camera] +!PREFERENCES_CUSTPROFBUILDPATH;Executable path +!PREFERENCES_CUSTPROFBUILD;Custom Processing Profile Builder +!PREFERENCES_CUTOVERLAYBRUSH;Crop mask color/transparency +!PREFERENCES_DARKFRAMEFOUND;Found +!PREFERENCES_DARKFRAMESHOTS;shots +!PREFERENCES_DARKFRAMETEMPLATES;templates +!PREFERENCES_DARKFRAME;Dark Frame +!PREFERENCES_DATEFORMATFRAME;Date Format +!PREFERENCES_DIRDARKFRAMES;Dark frames directory +!PREFERENCES_EDITORLAYOUT;Editor Layout +!PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar (de-select for low res display) +!PREFERENCES_FLATFIELDFOUND;Found +!PREFERENCES_FLATFIELDSDIR;Flat Fields directory +!PREFERENCES_FLATFIELDSHOTS;shots +!PREFERENCES_FLATFIELDTEMPLATES;templates +!PREFERENCES_FLATFIELD;Flat Field +!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_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). On Windows use "SystemDefault", "SystemAsterisk" etc. for system sounds. +!PREFERENCES_SND_LNGEDITPROCDONE;Editor processing done +!PREFERENCES_SND_TRESHOLDSECS;after secs +!PREFERENCES_SQUAREDETAILWINDOW;Square detail window (faster) +!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_USESYSTEMTHEME; Use system theme +!PREFERENCES_WORKFLOW;Layout +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_SAVEPPASTE;Parameters to save +!PROGRESSBAR_BADPIXELS;Bad pixels... +!PROGRESSBAR_CACORRECTION;CA correction... +!PROGRESSBAR_DARKFRAME;Darkframe... +!PROGRESSBAR_GREENEQUIL;Green equilibrate... +!PROGRESSBAR_LINEDENOISE;Line Denoise... +!PROGRESSBAR_LOADINGTHUMBS;Loading thumbnails... +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing Profile Saved +!PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists +!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\nthe 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_CHROMATABERR_LABEL;Chromatic Aberration +!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_DETAIL_AMOUNT;Amount +!TP_DIRPYRDENOISE_CHROMA;Chrominance +!TP_DIRPYRDENOISE_GAMMA;Gamma +!TP_DIRPYRDENOISE_LABEL;Noise reduction +!TP_DIRPYRDENOISE_LUMA;Luminance +!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_EQUALIZER_CONTRAST_MINUS;Contrast- +!TP_EQUALIZER_CONTRAST_PLUS;Contrast+ +!TP_EQUALIZER_FINEST;finest +!TP_EQUALIZER_LABEL;Wavelet equalizer +!TP_EQUALIZER_LARGEST;coarsest +!TP_EQUALIZER_NEUTRAL;Neutral +!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 +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in auto levels operation +!TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Highlight recovery threshold +!TP_EXPOSURE_SATURATION;Saturation +!TP_EXPO_AFTER; After interpolation (before RGB conversion) +!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_HLREC_BLEND;Blend +!TP_HSVEQUALIZER_CHANNEL;HSV Channel +!TP_HSVEQUALIZER_HUE;H +!TP_HSVEQUALIZER_LABEL;HSV Equalizer +!TP_HSVEQUALIZER_NEUTRAL;Neutral +!TP_HSVEQUALIZER_SAT;S +!TP_HSVEQUALIZER_VAL;V +!TP_ICM_BLENDCMSMATRIX;Blend highlights with matrix +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover blown highlights when using LUT based ICC profiles +!TP_ICM_INPUTCAMERAICC;Auto-matched camera-specific color profile +!TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profile. These profiles are more precise than simpler matrix ones. Available for some 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_PREFERREDPROFILE;Preferred DCP profile +!TP_ICM_PREFERREDPROFILE_1;Daylight +!TP_ICM_PREFERREDPROFILE_2;Tungsten +!TP_ICM_PREFERREDPROFILE_3;Fluorescent +!TP_ICM_PREFERREDPROFILE_4;Flash +!TP_IMPULSEDENOISE_LABEL;Impulse Noise Reduction +!TP_IMPULSEDENOISE_THRESH;Impulse NR Threshold +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid Color Shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space\nand apply Munsell correction +!TP_LABCURVE_BRIGHTNESS;Brightness +!TP_LABCURVE_BWTONING;B&W Toning +!TP_LABCURVE_BWTONING_TIP;With B&W Toning option enabled, the Lab Chromaticity, Cc and Ch curves are not in effect.\nToning can be achieved using the a and b curves +!TP_LABCURVE_CHROMATICITY;Chromaticity +!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 the Chromaticity +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to the Hue +!TP_LABCURVE_LABEL;Lab Adjustments +!TP_LABCURVE_RSTPROTECTION;Red and Skin Tones Protection +!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;Use CA correction +!TP_LENSPROFILE_USEDIST;Use distortion correction +!TP_LENSPROFILE_USEVIGN;Use vignette correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset exposure controls to neutral values +!TP_PERSPECTIVE_HORIZONTAL;Horizontal +!TP_PERSPECTIVE_LABEL;Perspective +!TP_PERSPECTIVE_VERTICAL;Vertical +!TP_PREPROCESS_GREENEQUIL;Green equilibration +!TP_PREPROCESS_HOTDEADPIXFILT;Apply hot/dead pixel filter +!TP_PREPROCESS_HOTDEADPIXTHRESH;Hot/dead pixel detection threshold +!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 (leader) +!TP_RAWEXPOS_LINEAR;White Point: Linear corr. factor +!TP_RAWEXPOS_PRESER;White Point: HL preserving corr.(EV) +!TP_RAWEXPOS_TWOGREEN;Two greens together +!TP_RAW_ALLENHANCE;Apply post demosaic artifact/noise reduction +!TP_RAW_DCBENHANCE;Apply DCB enhancement step +!TP_RAW_DCBITERATIONS;Number of DCB iterations +!TP_RAW_LABEL;Demosaicing +!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_RED;R +!TP_SHARPENEDGE_AMOUNT;Quantity +!TP_SHARPENEDGE_LABEL;Edges +!TP_SHARPENEDGE_PASSES;Iterations +!TP_SHARPENEDGE_THREE;Luminance only +!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 the Hue +!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_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 +!ZOOMPANEL_100;(100%) +!ZOOMPANEL_NEWCROPWINDOW;Open (new) detail window +!ZOOMPANEL_ZOOM100;Zoom to 100% 1 +!ZOOMPANEL_ZOOMFITSCREEN;Fit to screen F +!ZOOMPANEL_ZOOMIN;Zoom In + +!ZOOMPANEL_ZOOMOUT;Zoom Out - diff --git a/rtdata/languages/Hebrew b/rtdata/languages/Hebrew new file mode 100644 index 000000000..b957e99e4 --- /dev/null +++ b/rtdata/languages/Hebrew @@ -0,0 +1,1208 @@ +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_DIALOGLABEL;Exif Filter +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_ARRANGEMENTHINT;Change between vertical/horizontal alignment of thumbnails +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_EXIFFILTERAPPLYHINT;Switch on/off exif filter of the file browser +FILEBROWSER_EXIFFILTERAPPLY;Apply +FILEBROWSER_EXIFFILTERLABEL;Exif Filter +FILEBROWSER_EXIFFILTERSETTINGSHINT;Change settings of the exif filter +FILEBROWSER_EXIFFILTERSETTINGS;Setup +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_POPUPRANK1;Rank 1 +FILEBROWSER_POPUPRANK2;Rank 2 +FILEBROWSER_POPUPRANK3;Rank 3 +FILEBROWSER_POPUPRANK4;Rank 4 +FILEBROWSER_POPUPRANK5;Rank 5 +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_PROCESSINGSETTINGSHINT;Set the file format and output directory +FILEBROWSER_PROCESSINGSETTINGS;Settings +FILEBROWSER_RENAMEDLGLABEL;Rename file +FILEBROWSER_RENAMEDLGMSG;Rename file "%1" to: +FILEBROWSER_SHOWDIRHINT;Show all images of the directory +FILEBROWSER_SHOWQUEUEHINT;Show content of the processing queue +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_LOAD;הטען +GENERAL_NA;אין +GENERAL_NO;לא +GENERAL_OK;שמור +GENERAL_PORTRAIT;דיוקן +GENERAL_SAVE;שמור +GENERAL_YES;כן +HISTOGRAM_LABEL;Histogram +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_NEWSNAPSHOTAS;בשם +HISTORY_NEWSNAPSHOT;תצלום חדש +HISTORY_NEWSSDIALOGLABEL;שם התצלום +HISTORY_NEWSSDIALOGTITLE;הוסף תצלום חדש +HISTORY_SETTO;העבר אל +HISTORY_SNAPSHOTS;תצלומים +HISTORY_SNAPSHOT;תצלום +ICMPANEL_FILEDLGFILTERANY;קבצים כלשהם +ICMPANEL_FILEDLGFILTERICM;ICC קבצי צבע +ICMPANEL_GAMMABEFOREINPUT;Profile applies Gamma +ICMPANEL_INPUTCAMERA;ברירת מחדל המצלמה +ICMPANEL_INPUTCUSTOM;מותאם +ICMPANEL_INPUTDLGLABEL;בחר בפרופיל צבע ייבוא +ICMPANEL_INPUTEMBEDDED;השתמש בפרופיל משובץ,אם אפשר +ICMPANEL_INPUTPROFILE;פרופיל ייבוא +ICMPANEL_NOICM;sRGBללא ניהול צבע - ייצוא ב +ICMPANEL_OUTPUTDLGLABEL;בחר בפרופיל צבע ייצוא +ICMPANEL_OUTPUTPROFILE;פרופיל ייצוא +ICMPANEL_SAVEREFERENCE;Save reference image for profiling +ICMPANEL_WORKINGPROFILE;פרופיל עבודה +IMAGEAREA_DETAILVIEW;תצוגת פרטים +IPTCPANEL_AUTHORHINT;Name of the creator of the object, e.g. writer, photographer or graphic artist (By-line). +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_EXIT;Exit +MAIN_BUTTON_PREFERENCES;העדפויות +MAIN_BUTTON_QUEUE;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_EXITJOBSINQUEUEINFO;Unprocessed images in the queue will be lost on exit. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Are you sure you want to exit? There are unprocessed images waiting in the queue. +MAIN_MSG_JOBSINQUEUE;עבודות בתור +MAIN_MSG_QOVERWRITE;?רצונך לכתוב אותו מחדש? +MAIN_TAB_BASIC;יסודות +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_ICM;ניהול צבע +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;התמרות +MAIN_TOOLTIP_HIDEFP;גלה\הסתר לוח תחתון - דפדפן (shortcut key: F) +MAIN_TOOLTIP_HIDEHP;גלה\הסתר לוח שמאלי - היסטוריה (shortcut key: F) +MAIN_TOOLTIP_INDCLIPPEDH;סימן לגוונים בהירים מקוצצים +MAIN_TOOLTIP_INDCLIPPEDS;סימן לגוונים כהים מקוצצים +MAIN_TOOLTIP_PREFERENCES;קבע העדפויות +MAIN_TOOLTIP_QINFO;מידע מהיר אודות הצילום +MAIN_TOOLTIP_SAVEAS;שמור לתיק נבחר +MAIN_TOOLTIP_SAVE;שמור לתיק ברירת המחדל +PARTIALPASTE_BASICGROUP;Basic settings +PARTIALPASTE_CACORRECTION;C/A correction +PARTIALPASTE_COARSETRANS;90 deg rotation / flipping +PARTIALPASTE_COLORBOOST;Color boost +PARTIALPASTE_COLORDENOISE;Color denoise +PARTIALPASTE_COLORGROUP;Color related settings +PARTIALPASTE_COLORMIXER;Color mixer +PARTIALPASTE_COLORSHIFT;Color shift +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_HLRECOVERY;Highlight recovery +PARTIALPASTE_ICMSETTINGS;ICM settings +PARTIALPASTE_IPTCINFO;IPTC info +PARTIALPASTE_LENSGROUP;Lens related settings +PARTIALPASTE_LUMACURVE;Luminance curve +PARTIALPASTE_LUMADENOISE;Luminance noise reduction +PARTIALPASTE_LUMINANCEGROUP;Luminance related settings +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_CACHESTRAT1;Prefer Speed to Low Memory Consumption +PREFERENCES_CACHESTRAT2;Prefer Low Memory Consumption to Speed +PREFERENCES_CACHESTRAT;Cache Strategy +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_DEMOSAICINGALGO;אלגוריתם דימוזאיק +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_HINT;רמז +PREFERENCES_HLTHRESHOLD;סף קיצוץ עליון +PREFERENCES_ICCDIR;ICC תיקיית פרופילי צבע +PREFERENCES_IMPROCPARAMS;נתוני עיבוד ברירת המחדל +PREFERENCES_INTENT_ABSOLUTE;קולורמטרית מוחלטת +PREFERENCES_INTENT_PERCEPTUAL;תפיסתית +PREFERENCES_INTENT_RELATIVE;קולורמטרית יחסית +PREFERENCES_INTENT_SATURATION;רויה +PREFERENCES_LIVETHUMBNAILS;Live Thumbnails (slower) +PREFERENCES_MONITORICC;פרופיל מסך +PREFERENCES_OUTDIRFOLDERHINT;Put the saved images to the seledted folder +PREFERENCES_OUTDIRFOLDER;Save to folder +PREFERENCES_OUTDIRHINT;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_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_SELECTICCDIRDLG;ICC בחר תיקיית פרופילי צבע +PREFERENCES_SELECTLANG;בחר שפה +PREFERENCES_SELECTMONITORPROFDLG;של התצוגה ICC בחר פרופיל +PREFERENCES_SELECTTHEME;Select theme +PREFERENCES_SHOWBASICEXIF;Exif הראה מידע +PREFERENCES_SHOWDATETIME;הראה תאריך ושעה +PREFERENCES_SHOWONLYRAW;RAW הראה רק קבצי +PREFERENCES_SHTHRESHOLD;סף קיצוץ תחתון +PREFERENCES_STARTUPIMDIR;תיקיית צילומים באתחול +PREFERENCES_TAB_BROWSER;דפדפן קבצים +PREFERENCES_TAB_COLORMGR;ניהול צבעים +PREFERENCES_TAB_GENERAL;כללי +PREFERENCES_TAB_IMPROC;עיבוד צילום +PREFERENCES_TAB_OUTPUT;אפשרויות ייצוא +PREFERENCES_THUMBSIZE;גודל תמונות ממוזערות +PROFILEPANEL_FILEDLGFILTERANY;קבצים כלשהם +PROFILEPANEL_FILEDLGFILTERPP;פרופילי עיבוד +PROFILEPANEL_LABEL;פרופילי עיבוד +PROFILEPANEL_LOADDLGLABEL;הטען נתוני עיבוד +PROFILEPANEL_PCUSTOM;מותאם +PROFILEPANEL_PFILE;מקובץ +PROFILEPANEL_PLASTPHOTO;צילום אחרון +PROFILEPANEL_PLASTSAVED;נשמר אחרון +PROFILEPANEL_PROFILE;פרופיל +PROFILEPANEL_SAVEDLGLABEL;שמור נתוני עיבוד +PROFILEPANEL_TOOLTIPCOPY;Copy current profile to clipboard +PROFILEPANEL_TOOLTIPLOAD;הטען פרופיל מקובץ +PROFILEPANEL_TOOLTIPPASTE; Paste profile from clipboard +PROFILEPANEL_TOOLTIPSAVE;שמור פרופיל נוכחי +PROGRESSBAR_DECODING;מפענח קובץ +PROGRESSBAR_DEMOSAICING;מעבד צילום +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_FOCALLENGTH;אורך מוקד +QINFO_ISO;ISO +QINFO_LENS;Lens +QINFO_NOEXIF;המידע לא זמין +SAVEDLG_FILEFORMAT;תצורת קובץ +SAVEDLG_JPEGQUAL;JPEG איכות +SAVEDLG_JPGFILTER;JPEG קבצי +SAVEDLG_PNGCOMPR;PNG דחיסת +SAVEDLG_PNGFILTER;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_OUTPUTDLGLABEL;בחר בפרופיל צבע ייצוא +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_LUMADENOISE_EDGETOLERANCE;סבילות לקצוות +TP_LUMADENOISE_LABEL;הסרת רעש בהירות +TP_LUMADENOISE_RADIUS;רדיוס +TP_RAW_DMETHOD;שיטה +TP_RAW_FALSECOLOR;דחיית צבע מסולף +TP_RESIZE_BICUBICSF;ביקובי חלק +TP_RESIZE_BICUBICSH;ביקובי חד +TP_RESIZE_BICUBIC;ביקובי +TP_RESIZE_BILINEAR;בילינארי +TP_RESIZE_FULLSIZE;גודל מלא +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;מידת חום +ZOOMBAR_DETAIL;פרטים +ZOOMBAR_HUGE;ענק +ZOOMBAR_LARGE;גדול +ZOOMBAR_NORMAL;רגיל +ZOOMBAR_PREVIEW;תצוגה מקדימה +ZOOMBAR_SCALE;מידה +ZOOMBAR_SMALL;קטן + +#00 Hebrew +#01 21.02.2008: initially translated by ??? +# 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 +!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_SHARPENEDGE;Bypass Edge Sharpening +!EXPORT_BYPASS_SHARPENING;Bypass Sharpening +!EXPORT_BYPASS_SHARPENMICRO;Bypass Microcontrast +!EXPORT_BYPASS_SH_HQ;Bypass Shadow/Highlights (High Quality) +!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 the path text box.\nEnter / Ctrl-Enter (in the File Browser) to browse there;\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_CURRENT_NAME;Current name: +!FILEBROWSER_DARKFRAME;Dark frame +!FILEBROWSER_DELETEDLGMSGINCLPROC;Are you sure you want to delete the selected %1 files including a queue-processed version? +!FILEBROWSER_EXEC_CPB;Custom Profile Builder +!FILEBROWSER_EXTPROGMENU;Open with +!FILEBROWSER_FLATFIELD;Flat Field +!FILEBROWSER_MOVETODARKFDIR;Move to dark frames directory +!FILEBROWSER_MOVETOFLATFIELDDIR;Move to flat fields directory +!FILEBROWSER_NEW_NAME;New name: +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!FILEBROWSER_POPUPCOLORLABEL0;Label: None +!FILEBROWSER_POPUPCOLORLABEL1;Label: Red +!FILEBROWSER_POPUPCOLORLABEL2;Label: Yellow +!FILEBROWSER_POPUPCOLORLABEL3;Label: Green +!FILEBROWSER_POPUPCOLORLABEL4;Label: Blue +!FILEBROWSER_POPUPCOLORLABEL5;Label: Purple +!FILEBROWSER_POPUPCOLORLABEL;Color label +!FILEBROWSER_POPUPCOPYTO;Copy to... +!FILEBROWSER_POPUPFILEOPERATIONS;File Operations +!FILEBROWSER_POPUPMOVETO;Move to... +!FILEBROWSER_POPUPPROCESSFAST;Put to Queue (Fast export) +!FILEBROWSER_POPUPPROFILEOPERATIONS;Processing Profile Operations +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_POPUPREMOVESUBMENU;Remove +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!FILEBROWSER_QUERYHINT;Type a partial filename to search for.\nCtrl-F to focus the Find text box (in the File Browser).\nEnter to commence search. +!FILEBROWSER_QUERYLABEL; Find: +!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 +!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-` +!FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +!FILEBROWSER_USETEMPLATE;Use template: +!GENERAL_AFTER;After +!GENERAL_BEFORE;Before +!GENERAL_FILE;File +!GENERAL_HIGH_QUALITY;High Quality +!GENERAL_NONE;None +!GENERAL_UNCHANGED;(Unchanged) +!GENERAL_WARNING;Warning +!HISTOGRAM_BUTTON_BAR;RGB +!HISTOGRAM_BUTTON_B;B +!HISTOGRAM_BUTTON_G;G +!HISTOGRAM_BUTTON_L;L +!HISTOGRAM_BUTTON_RAW;Raw +!HISTOGRAM_BUTTON_R;R +!HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar\nClick right mouse button on image preview to freeze/unfreeze +!HISTOGRAM_TOOLTIP_FULL;Toggle full or scaled histogram +!HISTOGRAM_TOOLTIP_RAW;Show/Hide raw histogram +!HISTORY_MSG_82;Profile Changed +!HISTORY_MSG_83;High Quality Shadows/Highlights +!HISTORY_MSG_84;Perspective Correction +!HISTORY_MSG_85;Lens Correction Profile +!HISTORY_MSG_86;Wavelet Equalizer +!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 +!HISTORY_MSG_92;NR - Gamma +!HISTORY_MSG_93;Contrast by Detail Levels Value +!HISTORY_MSG_94;Contrast by Detail Levels +!HISTORY_MSG_95;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;RGB Saturation +!HISTORY_MSG_101;HSV EQ -- Hue +!HISTORY_MSG_102;HSV EQ -- Saturation +!HISTORY_MSG_103;HSV EQ -- Value +!HISTORY_MSG_104;HSV Equalizer +!HISTORY_MSG_105;Defringing +!HISTORY_MSG_106;Defringing Radius +!HISTORY_MSG_107;Defringing Threshold +!HISTORY_MSG_108;Highlight Compr. Threshold +!HISTORY_MSG_109;Resize Bounding Box +!HISTORY_MSG_110;Resizing applies o +!HISTORY_MSG_111;Avoid Color Shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;Red and Skin Tones Protection +!HISTORY_MSG_114;DCB Iterations +!HISTORY_MSG_115;False Color Iterations +!HISTORY_MSG_116;Enhanced DCB +!HISTORY_MSG_117;Red CA Correction +!HISTORY_MSG_118;Blue CA Correction +!HISTORY_MSG_119;Line Denoise +!HISTORY_MSG_120;Green Equil. Threshold +!HISTORY_MSG_121;Auto CA +!HISTORY_MSG_122;Auto Dark Frame +!HISTORY_MSG_123;Dark Frame File +!HISTORY_MSG_124;Linear Exp. Correction +!HISTORY_MSG_125;Exp. Correction Preserving HL +!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;Gamma +!HISTORY_MSG_134;Gamma Position +!HISTORY_MSG_135;Gamma Free +!HISTORY_MSG_136;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 Green Together +!HISTORY_MSG_142;Edges Sharpening - Iterations +!HISTORY_MSG_143;Edges Sharpening - Quantity +!HISTORY_MSG_144;Microcontrast - Quantity +!HISTORY_MSG_145;Microcontrast - Uniformity +!HISTORY_MSG_146;Edges Sharpening +!HISTORY_MSG_147;Edges Sharpening - 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;Vibrance - Pastel tones +!HISTORY_MSG_153;Vibrance - Saturated tones +!HISTORY_MSG_154;Vibrance - Protect skin tones +!HISTORY_MSG_155;Vibrance - Avoid color drift +!HISTORY_MSG_156;Vibrance - Link pastel and saturated tones +!HISTORY_MSG_157;Vibrance - Pastel/Saturated threshold +!HISTORY_MSG_158;Strength +!HISTORY_MSG_159;Edge Stopping +!HISTORY_MSG_160;Scale +!HISTORY_MSG_161;Reweighting Iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_163;RGB Curves - R +!HISTORY_MSG_164;RGB Curves - G +!HISTORY_MSG_165;RGB Curves - B +!HISTORY_MSG_166;Neutral Levels +!HISTORY_MSG_167;B&W Toning +!HISTORY_MSG_168;'Cc' curve +!HISTORY_MSG_169;'Ch' curve +!HISTORY_MSG_170;Vibrance - Curve +!MAIN_BUTTON_FULLSCREEN;Fullscreen +!MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Put current image to processing queue.\nShortcut: Ctrl+Q +!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_ERRORDURINGIMAGESAVING;Error during image saving +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue processed first. +!MAIN_MSG_NAVIGATOR;Navigator +!MAIN_MSG_PLACES;Places +!MAIN_TAB_COLOR_TOOLTIP;Shortcut: Alt-C +!MAIN_TAB_DETAIL_TOOLTIP;Shortcut: Alt-D +!MAIN_TAB_EXPORT; 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_TOGGLE_BEFORE_AFTER;B|A +!MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 8 +!MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 0 +!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_CHANNELMIXER;Channel mixer +!PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto fill +!PARTIALPASTE_DARKFRAMEAUTOSELECT;Dark Frame Auto Select +!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;FF Auto Select +!PARTIALPASTE_FLATFIELDBLURRADIUS;FF Blur Radius +!PARTIALPASTE_FLATFIELDBLURTYPE;FF Blur Type +!PARTIALPASTE_FLATFIELDFILE;Flat field (FF) File +!PARTIALPASTE_HLRECONSTRUCTION;Highlight reconstruction +!PARTIALPASTE_HLRECOVERYAMOUNT;Highlight recovery amount +!PARTIALPASTE_HLRECOVERYTHRESHOLD;Highlight recovery threshold +!PARTIALPASTE_HSVEQUALIZER;HSV Equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!PARTIALPASTE_LABCURVE;Lab adjustments +!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 Level +!PARTIALPASTE_RAWEXPOS_LINEAR;Raw white point linear corr. factor +!PARTIALPASTE_RAWEXPOS_PRESER;Raw white point HL preserving corr. (EV) +!PARTIALPASTE_RAWGROUP;Raw settings +!PARTIALPASTE_RAW_ALLENHANCE;Apply post demosaic artifact/noise reduction +!PARTIALPASTE_RAW_DCBENHANCE;Apply DCB enhancement step +!PARTIALPASTE_RAW_DCBITERATIONS;Number of DCB iterations +!PARTIALPASTE_RAW_DMETHOD;Demosaic Method +!PARTIALPASTE_RAW_FALSECOLOR;Demosaic False color suppression steps +!PARTIALPASTE_RGBCURVES;RGB curves +!PARTIALPASTE_SHARPENEDGE;Edges +!PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_VIBRANCE;Vibrance +!PARTIALPASTE_WAVELETEQUALIZER;Wavelet equalizer +!PREFERENCES_ADD;ADD +!PREFERENCES_AUTOMONPROFILE;Automatically use operating system's main monitor color profile +!PREFERENCES_BATCH_PROCESSING;Batch Processing +!PREFERENCES_BEHAVIOR;Behavior +!PREFERENCES_CUSTPROFBUILDHINT;Executable (or script) file called when a new initial processing profile should be generated for an image.\nReceives command line parameters to allow a rules-based processing profile generation:\n[raw/JPG path] [default processing profile path] [f-number] [exposure in secs] [focal length in mm] [ISO] [lens] [camera] +!PREFERENCES_CUSTPROFBUILDPATH;Executable path +!PREFERENCES_CUSTPROFBUILD;Custom Processing Profile Builder +!PREFERENCES_CUTOVERLAYBRUSH;Crop mask color/transparency +!PREFERENCES_DARKFRAMEFOUND;Found +!PREFERENCES_DARKFRAMESHOTS;shots +!PREFERENCES_DARKFRAMETEMPLATES;templates +!PREFERENCES_DARKFRAME;Dark Frame +!PREFERENCES_DATEFORMATFRAME;Date Format +!PREFERENCES_DIRDARKFRAMES;Dark frames directory +!PREFERENCES_EDITORLAYOUT;Editor Layout +!PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar (de-select for low res display) +!PREFERENCES_FLATFIELDFOUND;Found +!PREFERENCES_FLATFIELDSDIR;Flat Fields directory +!PREFERENCES_FLATFIELDSHOTS;shots +!PREFERENCES_FLATFIELDTEMPLATES;templates +!PREFERENCES_FLATFIELD;Flat Field +!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_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). On Windows use "SystemDefault", "SystemAsterisk" etc. for system sounds. +!PREFERENCES_SND_LNGEDITPROCDONE;Editor processing done +!PREFERENCES_SND_TRESHOLDSECS;after secs +!PREFERENCES_SQUAREDETAILWINDOW;Square detail window (faster) +!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_USESYSTEMTHEME; Use system theme +!PREFERENCES_WORKFLOW;Layout +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_SAVEPPASTE;Parameters to save +!PROGRESSBAR_BADPIXELS;Bad pixels... +!PROGRESSBAR_CACORRECTION;CA correction... +!PROGRESSBAR_DARKFRAME;Darkframe... +!PROGRESSBAR_GREENEQUIL;Green equilibrate... +!PROGRESSBAR_LINEDENOISE;Line Denoise... +!PROGRESSBAR_LOADINGTHUMBS;Loading thumbnails... +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing Profile Saved +!PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists +!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\nthe 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_CHROMATABERR_LABEL;Chromatic Aberration +!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_DETAIL_AMOUNT;Amount +!TP_DIRPYRDENOISE_CHROMA;Chrominance +!TP_DIRPYRDENOISE_GAMMA;Gamma +!TP_DIRPYRDENOISE_LABEL;Noise reduction +!TP_DIRPYRDENOISE_LUMA;Luminance +!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_EQUALIZER_CONTRAST_MINUS;Contrast- +!TP_EQUALIZER_CONTRAST_PLUS;Contrast+ +!TP_EQUALIZER_FINEST;finest +!TP_EQUALIZER_LABEL;Wavelet equalizer +!TP_EQUALIZER_LARGEST;coarsest +!TP_EQUALIZER_NEUTRAL;Neutral +!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 +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in auto levels operation +!TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Highlight recovery threshold +!TP_EXPOSURE_SATURATION;Saturation +!TP_EXPO_AFTER; After interpolation (before RGB conversion) +!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_HLREC_BLEND;Blend +!TP_HSVEQUALIZER_CHANNEL;HSV Channel +!TP_HSVEQUALIZER_HUE;H +!TP_HSVEQUALIZER_LABEL;HSV Equalizer +!TP_HSVEQUALIZER_NEUTRAL;Neutral +!TP_HSVEQUALIZER_SAT;S +!TP_HSVEQUALIZER_VAL;V +!TP_ICM_BLENDCMSMATRIX;Blend highlights with matrix +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover blown highlights when using LUT based ICC profiles +!TP_ICM_INPUTCAMERAICC;Auto-matched camera-specific color profile +!TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profile. These profiles are more precise than simpler matrix ones. Available for some 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_PREFERREDPROFILE;Preferred DCP profile +!TP_ICM_PREFERREDPROFILE_1;Daylight +!TP_ICM_PREFERREDPROFILE_2;Tungsten +!TP_ICM_PREFERREDPROFILE_3;Fluorescent +!TP_ICM_PREFERREDPROFILE_4;Flash +!TP_IMPULSEDENOISE_LABEL;Impulse Noise Reduction +!TP_IMPULSEDENOISE_THRESH;Impulse NR Threshold +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid Color Shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space\nand apply Munsell correction +!TP_LABCURVE_BRIGHTNESS;Brightness +!TP_LABCURVE_BWTONING;B&W Toning +!TP_LABCURVE_BWTONING_TIP;With B&W Toning option enabled, the Lab Chromaticity, Cc and Ch curves are not in effect.\nToning can be achieved using the a and b curves +!TP_LABCURVE_CHROMATICITY;Chromaticity +!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 the Chromaticity +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to the Hue +!TP_LABCURVE_LABEL;Lab Adjustments +!TP_LABCURVE_RSTPROTECTION;Red and Skin Tones Protection +!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;Use CA correction +!TP_LENSPROFILE_USEDIST;Use distortion correction +!TP_LENSPROFILE_USEVIGN;Use vignette correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset exposure controls to neutral values +!TP_PERSPECTIVE_HORIZONTAL;Horizontal +!TP_PERSPECTIVE_LABEL;Perspective +!TP_PERSPECTIVE_VERTICAL;Vertical +!TP_PREPROCESS_GREENEQUIL;Green equilibration +!TP_PREPROCESS_HOTDEADPIXFILT;Apply hot/dead pixel filter +!TP_PREPROCESS_HOTDEADPIXTHRESH;Hot/dead pixel detection threshold +!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 (leader) +!TP_RAWEXPOS_LINEAR;White Point: Linear corr. factor +!TP_RAWEXPOS_PRESER;White Point: HL preserving corr.(EV) +!TP_RAWEXPOS_TWOGREEN;Two greens together +!TP_RAW_ALLENHANCE;Apply post demosaic artifact/noise reduction +!TP_RAW_DCBENHANCE;Apply DCB enhancement step +!TP_RAW_DCBITERATIONS;Number of DCB iterations +!TP_RAW_LABEL;Demosaicing +!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_RED;R +!TP_SHARPENEDGE_AMOUNT;Quantity +!TP_SHARPENEDGE_LABEL;Edges +!TP_SHARPENEDGE_PASSES;Iterations +!TP_SHARPENEDGE_THREE;Luminance only +!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 the Hue +!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_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 +!ZOOMPANEL_100;(100%) +!ZOOMPANEL_NEWCROPWINDOW;Open (new) detail window +!ZOOMPANEL_ZOOM100;Zoom to 100% 1 +!ZOOMPANEL_ZOOMFITSCREEN;Fit to screen F +!ZOOMPANEL_ZOOMIN;Zoom In + +!ZOOMPANEL_ZOOMOUT;Zoom Out - diff --git a/rtdata/languages/Italian b/rtdata/languages/Italian new file mode 100644 index 000000000..c3ca1d0a0 --- /dev/null +++ b/rtdata/languages/Italian @@ -0,0 +1,1209 @@ +ABOUT_TAB_BUILD;Versione +ABOUT_TAB_CREDITS;Riconoscimenti +ABOUT_TAB_LICENSE;Licenza +ABOUT_TAB_SPLASH;Emblema +ADJUSTER_RESET_TO_DEFAULT;Ritorna all'originario +BATCHQUEUE_AUTOSTART;Autoavvia +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_DIALOGLABEL;Filtro Exif +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 il campo selezionato nei dati finali +EXIFPANEL_KEEP;Mantieni +EXIFPANEL_REMOVEHINT;Rimuovi il campo selezionato dai dati finali +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 +FILEBROWSER_ADDDELTEMPLATE;Aggiungi/Rimuovi schemi... +FILEBROWSER_APPLYPROFILE;Applica un profilo +FILEBROWSER_APPLYPROFILE_PARTIAL;Applica un profilo (parziale) +FILEBROWSER_ARRANGEMENTHINT;Commuta fra la disposizione verticale o orizzontale delle miniature +FILEBROWSER_AUTODARKFRAME;Dark-Frame automatico +FILEBROWSER_AUTOFLATFIELD;Flat-Field automatico +FILEBROWSER_BROWSEPATHBUTTONHINT;Premi per posizionarsi secondo il percorso inserito +FILEBROWSER_BROWSEPATHHINT;Inserisci la destinazione da raggiungere\nCtrl-o seleziona il percorso\nEnter, Ctrl-Enter (solo nel Navigatore) porta alla destinazione ;\nPercorsi abbreviati:\n ~ - Cartella personale dell'utente (home directory)\n ! - Cartella delle Immagini dell'utente +FILEBROWSER_CACHECLEARFROMFULL;Rimuovi dalla memoria - totale +FILEBROWSER_CACHECLEARFROMPARTIAL;Rimuovi dalla memoria - parziale +FILEBROWSER_CACHE;Memoria del programma +FILEBROWSER_CLEARPROFILE;Azzera il profilo +FILEBROWSER_COPYPROFILE;Copia il profilo +FILEBROWSER_CURRENT_NAME;Nome corrente: +FILEBROWSER_DARKFRAME;Dark-Frame +FILEBROWSER_DELETEDLGLABEL;Conferma di eliminazione del file +FILEBROWSER_DELETEDLGMSGINCLPROC;Sei certo di voler eliminare il/i %1 file INCLUSA una versione sviluppata nella coda? +FILEBROWSER_DELETEDLGMSG;Sei certo di voler eliminare il/i %1 file selezionato/i? +FILEBROWSER_EMPTYTRASHHINT;Elimina definitivamente i file dal cestino +FILEBROWSER_EMPTYTRASH;Svuota cestino +FILEBROWSER_EXEC_CPB;Avvia lo strumento per la generazione dei profili su misura +FILEBROWSER_EXIFFILTERAPPLYHINT;Accendi/Spegni il filtro exif nel navigatore +FILEBROWSER_EXIFFILTERAPPLY;Applica +FILEBROWSER_EXIFFILTERLABEL;Filtro Exif +FILEBROWSER_EXIFFILTERSETTINGSHINT;Modifica le impostazioni del filtro exif +FILEBROWSER_EXIFFILTERSETTINGS;Imposta +FILEBROWSER_FLATFIELD;Flat-Field +FILEBROWSER_MOVETODARKFDIR;Sposta nella cartella dei Dark-Frame +FILEBROWSER_MOVETOFLATFIELDDIR;Sposta nella cartella dei Flat-Fields +FILEBROWSER_NEW_NAME;Nuovo nome: +FILEBROWSER_PARTIALPASTEPROFILE;Incolla parzialmente il profilo +FILEBROWSER_PASTEPROFILE;Incolla il profilo +FILEBROWSER_POPUPCANCELJOB;Cancella questo lavoro +FILEBROWSER_POPUPCOLORLABEL0;Targhetta: assente +FILEBROWSER_POPUPCOLORLABEL1;Targhetta: rossa +FILEBROWSER_POPUPCOLORLABEL2;Targhetta: gialla +FILEBROWSER_POPUPCOLORLABEL3;Targhetta: verde +FILEBROWSER_POPUPCOLORLABEL4;Targhetta: blu +FILEBROWSER_POPUPCOLORLABEL5;Targhetta: viola +FILEBROWSER_POPUPCOLORLABEL;Targhetta 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_POPUPPROCESS;Invia alla coda di sviluppo +FILEBROWSER_POPUPPROFILEOPERATIONS;Operazioni sui profili +FILEBROWSER_POPUPRANK1;Classificazione 1 * +FILEBROWSER_POPUPRANK2;Classificazione 2 ** +FILEBROWSER_POPUPRANK3;Classificazione 3 *** +FILEBROWSER_POPUPRANK4;Classificazione 4 **** +FILEBROWSER_POPUPRANK5;Classificazione 5 ***** +FILEBROWSER_POPUPRANK;Classificazione +FILEBROWSER_POPUPREMOVEINCLPROC;Elimina (assieme a quanto sviluppato nella coda) +FILEBROWSER_POPUPREMOVESUBMENU;Elimina +FILEBROWSER_POPUPREMOVE;Elimina dal disco fisso +FILEBROWSER_POPUPRENAME;Rinomina +FILEBROWSER_POPUPSELECTALL;Seleziona tutto +FILEBROWSER_POPUPTRASH;Butta nel cestino +FILEBROWSER_POPUPUNRANK;Declassifica +FILEBROWSER_POPUPUNTRASH;Togli dal cestino +FILEBROWSER_PROCESSINGSETTINGSHINT;Scegli il formato del file e la cartella di destinazione +FILEBROWSER_PROCESSINGSETTINGS;Impostazioni +FILEBROWSER_QUERYBUTTONHINT;Azzera la ricerca +FILEBROWSER_QUERYHINT;Scrivi una parte del nome del file da cercare \nCtrl-f seleziona la parola (solo nel Navigatore);\nEnter per avviare la ricerca +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 targhetta Rossa Alt-1 +FILEBROWSER_SHOWCOLORLABEL2HINT;Mostra le immagini con targhetta Gialla Alt-2 +FILEBROWSER_SHOWCOLORLABEL3HINT;Mostra le immagini con targhetta Verde Alt-3 +FILEBROWSER_SHOWCOLORLABEL4HINT;Mostra le immagini con targhetta Blu Alt-4 +FILEBROWSER_SHOWCOLORLABEL5HINT;Mostra le immagini con targhetta Viola Alt-5 +FILEBROWSER_SHOWDIRHINT;Mostra tutte le immagini della cartella (scorciatoia: D) +FILEBROWSER_SHOWEDITEDHINT;Mostra immagini modificate 7 +FILEBROWSER_SHOWEDITEDNOTHINT;Mostra immagini non modificate 6 +FILEBROWSER_SHOWEXIFINFO;Mostra informazioni EXIF (scorciatoia: i) +FILEBROWSER_SHOWQUEUEHINT;Mostra il contenuto della coda di sviluppo +FILEBROWSER_SHOWRANK1HINT;Mostra le immagini classificate con 1 stella (scorciatoia: 1) +FILEBROWSER_SHOWRANK2HINT;Mostra le immagini classificate con 2 stelle (scorciatoia: 2) +FILEBROWSER_SHOWRANK3HINT;Mostra le immagini classificate con 3 stelle (scorciatoia: 3) +FILEBROWSER_SHOWRANK4HINT;Mostra le immagini classificate con 4 stelle (scorciatoia: 4) +FILEBROWSER_SHOWRANK5HINT;Mostra le immagini classificate con 5 stelle (scorciatoia: 5) +FILEBROWSER_SHOWRECENTLYSAVEDHINT;Mostra le immagini salvate di recente (scorciatoia: Alt-7) +FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Mostra le immagini salvate non di recente (scorciatoia: Alt-6) +FILEBROWSER_SHOWTRASHHINT;Mostra il contenuto del cestino (scorciatoia: T) +FILEBROWSER_SHOWUNCOLORHINT;Mostra le immagini senza targhetta colorata (scorciatoia: Alt-` +FILEBROWSER_SHOWUNRANKHINT;Mostra le immagini non classificate (scorciatoia: `) +FILEBROWSER_STARTPROCESSINGHINT;Inizia lo sviluppo e il salvataggio delle immagini in coda +FILEBROWSER_STARTPROCESSING;Comincia a sviluppare +FILEBROWSER_STOPPROCESSINGHINT;Ferma lo sviluppo delle immagini +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 (scorciatoia: +) +FILEBROWSER_ZOOMOUTHINT;Diminuisci la dimensione delle miniature (scorciatoia: -) +GENERAL_ABOUT;Informazioni +GENERAL_AFTER;Dopo +GENERAL_BEFORE;Prima +GENERAL_CANCEL;Annulla +GENERAL_DISABLED;Disabilitato +GENERAL_DISABLE;Disabilita +GENERAL_ENABLED;Abilitato +GENERAL_ENABLE;Abilita +GENERAL_FILE;File +GENERAL_HIGH_QUALITY;Qualità alta +GENERAL_LANDSCAPE;Panorama +GENERAL_LOAD;Carica +GENERAL_NA;n/d +GENERAL_NONE;Nessuno +GENERAL_NO;No +GENERAL_OK;OK +GENERAL_PORTRAIT;Ritratto +GENERAL_SAVE;Salva +GENERAL_UNCHANGED;(Invariante) +GENERAL_YES;Sì +HISTOGRAM_BUTTON_BAR;RGB +HISTOGRAM_BUTTON_B;B +HISTOGRAM_BUTTON_G;G +HISTOGRAM_BUTTON_L;L +HISTOGRAM_BUTTON_RAW;Raw +HISTOGRAM_BUTTON_R;R +HISTOGRAM_LABEL;Istogramma +HISTOGRAM_TOOLTIP_BAR;Mostra/Nascondi la barra indicatrice 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_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à - Esposizione +HISTORY_MSG_6;Contrasto - Esposizione +HISTORY_MSG_7;Livello del nero - Esposizione +HISTORY_MSG_8;Compensazione dell'esposizione +HISTORY_MSG_9;Compressione alteluci +HISTORY_MSG_10;Compressione ombre +HISTORY_MSG_11;Curva di tono +HISTORY_MSG_12;Esposizione automatica +HISTORY_MSG_13;Tosaggio - Esposizione +HISTORY_MSG_14;Luminosità - Luminanza +HISTORY_MSG_15;Contrasto - Luminanza +HISTORY_MSG_16;Livello del nero - Luminanza +HISTORY_MSG_17;Compr. alteluci - Luminanza +HISTORY_MSG_18;Compr. ombre - Luminanza +HISTORY_MSG_19;Curva per 'L' +HISTORY_MSG_20;Nitidezza +HISTORY_MSG_21;Raggio - Nitidezza +HISTORY_MSG_22;Quantità - Nitidezza +HISTORY_MSG_23;Soglia - Nitidezza +HISTORY_MSG_24;Definisci solo i bordi +HISTORY_MSG_25;Raggio di rilevamento bordi - Nitidezza +HISTORY_MSG_26;Tolleranza bordi - Nitidezza +HISTORY_MSG_27;Controllo alone - Nitidezza +HISTORY_MSG_28;Quantità - Controllo alone +HISTORY_MSG_29;Metodo - Nitidezza +HISTORY_MSG_30;Raggio - Deconvoluzione +HISTORY_MSG_31;Quantità - Deconvoluzione +HISTORY_MSG_32;Smorzamento - Deconvoluzione +HISTORY_MSG_33;Iterazioni - Deconvoluzione +HISTORY_MSG_34;Previeni tosaggio dei colori +HISTORY_MSG_35;Limitatore di saturazione +HISTORY_MSG_36;Limite saturazione +HISTORY_MSG_37;Potenziamento colore +HISTORY_MSG_38;Metodo - Bilanciamento del bianco +HISTORY_MSG_39;Temperatura di colore +HISTORY_MSG_40;Tinta - Bilanciamento del bianco +HISTORY_MSG_41;Spostamento colore "a" +HISTORY_MSG_42;Spostamento colore "b" +HISTORY_MSG_43;Riduzione rumore luminanza +HISTORY_MSG_44;Raggio - Rid. rumore luminanza +HISTORY_MSG_45;Tolleranza bordi- Rid. rumore luminanza +HISTORY_MSG_46;Riduzione rumore crominanza +HISTORY_MSG_47;Raggio - Rid. rumore crominanza +HISTORY_MSG_48;Tolleranza bordi - Rid. rumore crominanza +HISTORY_MSG_49;Sensibilità bordi - Rid. rumore crominanza +HISTORY_MSG_50;Strumento Ombre/Alteluci +HISTORY_MSG_51;Miglioramento alteluci +HISTORY_MSG_52;Miglioramento ombre +HISTORY_MSG_53;Ampiezza tonale - Alteluci +HISTORY_MSG_54;Ampiezza tonale - Ombre +HISTORY_MSG_55;Contrasto locale +HISTORY_MSG_56;Raggio - Ombre/Alteluci +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;Recupero alteluci +HISTORY_MSG_67;Quantità - Recupero alteluci +HISTORY_MSG_68;Metodo - Ricostruzione alteluci +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;Scala - Ridimensiona +HISTORY_MSG_75;Metodo - Ridimensiona +HISTORY_MSG_76;Metadati Exif +HISTORY_MSG_77;Metadati IPTC +HISTORY_MSG_78;Misure specificate per ridimensiona +HISTORY_MSG_79;Larghezza - Ridimensiona +HISTORY_MSG_80;Altezza - Ridimensiona +HISTORY_MSG_81;Ridimensiona +HISTORY_MSG_82;Profilo modificato +HISTORY_MSG_83;Ombre/Alteluci con qualità alta +HISTORY_MSG_84;Correzione prospettiva +HISTORY_MSG_85;Coefficienti Wavelet +HISTORY_MSG_86;Equalizzatore Wavelet +HISTORY_MSG_87;Riduzione rumore puntuale +HISTORY_MSG_88;Soglia - Riduzione rumore puntuale +HISTORY_MSG_89;Riduzione rumore +HISTORY_MSG_90;Luminanza - Riduzione rumore +HISTORY_MSG_91;Crominanza - Riduzione rumore +HISTORY_MSG_92;Gamma - Riduzione rumore +HISTORY_MSG_93;Valore - Contrasto per livelli di dettaglio +HISTORY_MSG_94;Contrasto per livelli di dettaglio +HISTORY_MSG_95;Saturazione - Regolazioni Lab +HISTORY_MSG_96;Curva per 'a' +HISTORY_MSG_97;Curva per 'b' +HISTORY_MSG_98;Metodo - Demosaicizzazione +HISTORY_MSG_99;Interpolazione dei pixel alterati/guasti +HISTORY_MSG_100;Saturazione RGB +HISTORY_MSG_101;Tonalità - Equalizzatore HSV +HISTORY_MSG_102;Saturazione - Equalizzatore HSV +HISTORY_MSG_103;Luminosità - Equalizzatore HSV +HISTORY_MSG_104;Equalizzatore HSV +HISTORY_MSG_105;Rimozione aloni contrastati +HISTORY_MSG_106;Raggio - Rimozione aloni contrastati +HISTORY_MSG_107;Soglia - Rimozione aloni contrastati +HISTORY_MSG_108;Soglia di compr. alteluci +HISTORY_MSG_109;Riquadro di selezione - Ridimensiona +HISTORY_MSG_110;Ridimensiona applicato a +HISTORY_MSG_111;Previeni tosaggio del colore +HISTORY_MSG_112;Limitatore di saturazione +HISTORY_MSG_113;Limite saturazione +HISTORY_MSG_114;Iterazioni DCB +HISTORY_MSG_115;Stadi per falsi colori +HISTORY_MSG_116;Affinamento DCB +HISTORY_MSG_118;Correzione AC Blu +HISTORY_MSG_119;Filtro rumore a bande +HISTORY_MSG_120;Soglia uniform. verde +HISTORY_MSG_121;AC automatiche +HISTORY_MSG_122;Dark-Frame automatica +HISTORY_MSG_123;File di Dark-Frame +HISTORY_MSG_124;Compensazione esp. lineare +HISTORY_MSG_125;Comp. di protezione alteLuci +HISTORY_MSG_126;File di Flat-Field +HISTORY_MSG_127;Autoselezione Flat-Field +HISTORY_MSG_128;Raggio di sfocamento per Flat-Field +HISTORY_MSG_129;Modalità di sfocamento per Flat-Field +HISTORY_MSG_130;Autocorr. Distorsione +HISTORY_MSG_131;Riduzione rum. luminanza +HISTORY_MSG_132;Riduzione rum. crominanza +HISTORY_MSG_133;Gamma +HISTORY_MSG_134;Posizione del Gamma +HISTORY_MSG_135;Gamma libero +HISTORY_MSG_136;Pendenza - Gamma +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;Unico valore per verde +HISTORY_MSG_142;Iterazioni - Gradiente ai margini +HISTORY_MSG_143;Quantità - Gradiente ai margini +HISTORY_MSG_144;Quantità - Microcontrasto +HISTORY_MSG_145;Uniformità - Microcontrasto +HISTORY_MSG_146;Gradiente ai margini +HISTORY_MSG_147;Solo per luminanza - Gradiente ai margini +HISTORY_MSG_148;Microcontrasto +HISTORY_MSG_149;Matrice 3x3 - Microcontrasto +HISTORY_MSG_150;Limita rumore/artefatti di demosaic. +HISTORY_NEWSNAPSHOTAS;Come... +HISTORY_NEWSNAPSHOT;Aggiungi +HISTORY_NEWSSDIALOGLABEL;Etichetta dell'istantanea: +HISTORY_NEWSSDIALOGTITLE;Aggiungi nuova istantanea +HISTORY_SETTO;Impostato a +HISTORY_SNAPSHOTS;Istantanee +HISTORY_SNAPSHOT;Istantanea +ICMPANEL_FILEDLGFILTERANY;Qualsiasi file +ICMPANEL_FILEDLGFILTERICM;File di Profili ICC +ICMPANEL_GAMMABEFOREINPUT;Il profilo applica il Gamma +ICMPANEL_INPUTCAMERA;Predefinito della fotocamera +ICMPANEL_INPUTCUSTOM;Personalizzato +ICMPANEL_INPUTDLGLABEL;Seleziona il profilo ICC di ingresso... +ICMPANEL_INPUTEMBEDDED;Incorporato, se disponibile +ICMPANEL_INPUTPROFILE;Profilo di ingresso +ICMPANEL_NOICM;Nessun ICM: uscita in sRGB +ICMPANEL_OUTPUTDLGLABEL;Seleziona il profilo ICC di uscita... +ICMPANEL_OUTPUTPROFILE;Profilo di uscita +ICMPANEL_SAVEREFERENCE;Salva immagine di riferimento per la profilazione +ICMPANEL_WORKINGPROFILE;Profilo di lavoro +IMAGEAREA_DETAILVIEW;Visualizza dettaglio +IPTCPANEL_AUTHORHINT;Nome del creatore dell'opera, es. scrittore, fotografo o artista grafico (By-line). +IPTCPANEL_AUTHORSPOSITIONHINT;Titolo lavorativo 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 curatore (Category). +IPTCPANEL_CATEGORY;Categoria +IPTCPANEL_CITYHINT;Città o luogo 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 affinamento 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. +ISTORY_MSG_117;Correzione AC Rossa +MAIN_BUTTON_EXIT;Esci +MAIN_BUTTON_FULLSCREEN;Schermo intero +MAIN_BUTTON_PREFERENCES;Preferenze +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Aggiungi l'immagine corrente alla coda di sviluppo (scorciatoia: Ctrl+Q) +MAIN_BUTTON_QUEUE;Accoda +MAIN_BUTTON_SAVE_TOOLTIP;Salva l'immagine corrente (scorciatoia: Ctrl+S) +MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Modifica l'immagine corrente con un programma di ritocco grafico (scorciatoia: Ctrl+E) +MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Mostra/Nascondi tutti i pannelli laterali (scorciatoia: m) +MAIN_BUTTON_UNFULLSCREEN;Esci da schermo intero +MAIN_FRAME_BATCHQUEUE;Coda di sviluppo +MAIN_FRAME_BATCHQUEUE_TOOLTIP; Coda di sviluppo (scorciatoia: Ctrl-F3) +MAIN_FRAME_EDITOR;Sviluppo +MAIN_FRAME_EDITOR_TOOLTIP; Sviluppatore (scorciatoia: Ctrl-F4) +MAIN_FRAME_FILEBROWSER;Navigatore +MAIN_FRAME_FILEBROWSER_TOOLTIP; Navigatore (scorciatoia: 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 ritocco. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Si prega d'inserire il percorso corretto mediante l'impostazione nelle "Preferenze". +MAIN_MSG_EMPTYFILENAME;Nome del file non specificato! +MAIN_MSG_ERRORDURINGIMAGESAVING;Errore durante il salvataggio dell'immagine +MAIN_MSG_EXITJOBSINQUEUEINFO;Uscendo si perderanno le immagini in coda non ancora sviluppate. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Sei certo di voler uscire? Ci sono immagini non ancora sviluppate rimaste nella coda. +MAIN_MSG_JOBSINQUEUE;lavoro/i in coda +MAIN_MSG_NAVIGATOR;Navigatore +MAIN_MSG_PLACES;Risorse +MAIN_MSG_QOVERWRITE;Intendi sovrascriverlo? +MAIN_TAB_BASIC;Principale +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_EXPOSURE;Esposizione +MAIN_TAB_EXPOSURE_TOOLTIP;(scorciatoia: Alt-e) +MAIN_TAB_FILTER;Filtro +MAIN_TAB_ICM;ICM +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;Etichette +MAIN_TAB_TRANSFORM;Trasformazione +MAIN_TAB_TRANSFORM_TOOLTIP;(scorciatoia: Alt-t) +MAIN_TOGGLE_BEFORE_AFTER;P|D +MAIN_TOOLTIP_HIDEFP;Mostra/Nascondi il pannello dei pulsanti (cartelle e navigatore di file; scorciatoia: F) +MAIN_TOOLTIP_HIDEHP;Mostra/Nascondi il pannello sinistro (inclusa la cronologia; scorciatoia: H) +MAIN_TOOLTIP_INDCLIPPEDH;Indicazione delle alteluci tosate +MAIN_TOOLTIP_INDCLIPPEDS;Indicazione delle ombre tosate +MAIN_TOOLTIP_PREFERENCES;Imposta preferenze +MAIN_TOOLTIP_QINFO;Informazioni generali sullo scatto (scorciatoia: I) +MAIN_TOOLTIP_SAVEAS;Salva l'immagine nella cartella selezionata +MAIN_TOOLTIP_SAVE;Salva l'immagine nella cartella predefinita +MAIN_TOOLTIP_SHOWHIDELP1;Mostra/Nascondi il pannello sinistro (scorciatoia: l) +MAIN_TOOLTIP_SHOWHIDERP1;Mostra/Nascondi il pannello destro (scorciatoia: Alt-l) +MAIN_TOOLTIP_SHOWHIDETP1;Mostra/Nascondi il pannello superiore (scorciatoia: Shift-l) +MAIN_TOOLTIP_TOGGLE;Confronto prima/dopo (scorciatoia: 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_NA;x = n/d, y = n/d +PARTIALPASTE_BASICGROUP;Parametri principali +PARTIALPASTE_CACORRECTION;Correzione aberrazioni cromatiche +PARTIALPASTE_CHANNELMIXER;Miscelatore canali +PARTIALPASTE_COARSETRANS;Rotazione di 90° / Riflessione +PARTIALPASTE_COLORBOOST;Potenziamento colore +PARTIALPASTE_COLORDENOISE;Riduzione rumore di crominanza +PARTIALPASTE_COLORGROUP;Parametri relativi al colore +PARTIALPASTE_COLORMIXER;Miscelatore colore +PARTIALPASTE_COLORSHIFT;Spostamento 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;Rimozione aloni contrastati +PARTIALPASTE_DETAILGROUP;Parametri di dettaglio +PARTIALPASTE_DIALOGLABEL;Incolla una porzione del profilo +PARTIALPASTE_DIRPYRDENOISE;Riduzione rumore +PARTIALPASTE_DIRPYREQUALIZER;Contrasto per livelli di dettaglio +PARTIALPASTE_DISTORTION;Correzione distorsione +PARTIALPASTE_EVERYTHING;Tutto +PARTIALPASTE_EXIFCHANGES;Cambiamenti nei dati Exif +PARTIALPASTE_EXPOSURE;Esposizione +PARTIALPASTE_FLATFIELDAUTOSELECT;Autoselezione FF +PARTIALPASTE_FLATFIELDBLURRADIUS;Raggio di sfocamento FF +PARTIALPASTE_FLATFIELDBLURTYPE;Modalità di sfocamento FF +PARTIALPASTE_FLATFIELDFILE;File di Flat-Field +PARTIALPASTE_HLRECONSTRUCTION;Ricostruzione alteluci +PARTIALPASTE_HLRECOVERYAMOUNT;Quantità di recupero alteluci +PARTIALPASTE_HLRECOVERYTHRESHOLD;Soglia di recupero alteluci +PARTIALPASTE_HLRECOVERY;Recupero alteluci +PARTIALPASTE_HSVEQUALIZER;Equalizzatore HSV +PARTIALPASTE_ICMSETTINGS;Impostazioni ICM +PARTIALPASTE_IMPULSEDENOISE;Riduzione rumore puntuale +PARTIALPASTE_IPTCINFO;Informazioni IPTC +PARTIALPASTE_LABCURVE;Regolazioni Lab +PARTIALPASTE_LENSGROUP;Parametri correlati all'ottica +PARTIALPASTE_LUMADENOISE;Riduzione rumore di luminanza +PARTIALPASTE_LUMINANCEGROUP;Parametri riguardanti la luminanza +PARTIALPASTE_METAICMGROUP;Parametri di metadati e ICM +PARTIALPASTE_PERSPECTIVE;Prospettiva +PARTIALPASTE_PREPROCESS_GREENEQUIL;Uniformazione del verde +PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Interpolazione 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 rosse +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;Parametri di elaborazione raw +PARTIALPASTE_RAW_ALLENHANCE;Limita rumore/artefatti dovuti alla demosaicizzazione +PARTIALPASTE_RAW_DCBENHANCE;Fase di affinamento per DCB +PARTIALPASTE_RAW_DCBITERATIONS;Numero di iterazioni DCB +PARTIALPASTE_RAW_DMETHOD;Metodo di demosaicizzazione +PARTIALPASTE_RAW_FALSECOLOR;Soppressione di falsi colori demosaicizzati +PARTIALPASTE_RESIZE;Ridimensionamento +PARTIALPASTE_ROTATION;Rotazione +PARTIALPASTE_SHADOWSHIGHLIGHTS;Ombre/Alteluci +PARTIALPASTE_SHARPENEDGE;Bordi +PARTIALPASTE_SHARPENING;Nitidezza +PARTIALPASTE_SHARPENMICRO;Microcontrasto +PARTIALPASTE_VIGNETTING;Correzione Vignettatura +PARTIALPASTE_WAVELETEQUALIZER;Equalizzatore Wavelet +PARTIALPASTE_WHITEBALANCE;Bilanciamento del bianco +PREFERENCES_ADD;SOMMA +PREFERENCES_APPLNEXTSTARTUP;applicato al prossimo avvio +PREFERENCES_AUTOMONPROFILE;Usa automaticamente il profilo dello schermo principale del sistema operativo +PREFERENCES_BATCH_PROCESSING;Sviluppo in serie +PREFERENCES_BEHAVIOR;Comportamento +PREFERENCES_BLINKCLIPPED;Lampeggia le aree tosate +PREFERENCES_CACHECLEARALL;Rimuovi tutto +PREFERENCES_CACHECLEARPROFILES;Rimuovi i profili +PREFERENCES_CACHECLEARTHUMBS;Rimuovi le miniature +PREFERENCES_CACHEFORMAT1;Proprietario (più rapido e di migliore qualità) +PREFERENCES_CACHEFORMAT2;JPEG (minore impatto sul disco) +PREFERENCES_CACHEMAXENTRIES;Numero massimo di oggetti conservati in memoria +PREFERENCES_CACHEOPTS;Opzioni relative alla memoria del programma +PREFERENCES_CACHESTRAT1;Privilegia la rapidità al minore consumo di memoria +PREFERENCES_CACHESTRAT2;Privilegia il minore consumo di memoria alla rapidità +PREFERENCES_CACHESTRAT;Strategia di precaricamento +PREFERENCES_CACHETHUMBFORM;Formato delle miniature precaricate +PREFERENCES_CACHETHUMBHEIGHT;Massima altezza delle miniature +PREFERENCES_CLIPPINGIND;Indicazione di tosaggio +PREFERENCES_CMETRICINTENT;Intento colorimetrico +PREFERENCES_CUSTPROFBUILDHINT;Un file eseguibile (o uno script) richiamato quando è necessario generare un nuovo profilo per un'immagine.\nRisponde a parametri da linea di commando per permettere di generare .pp3 basati su regole quali:\n[Percorso del RAW/JPG] [Percorso del profilo predefinito] [f-stop] [esposizione in secondi] [focale in mm] [ISO] [Obiettivo] [Fotocamera] +PREFERENCES_CUSTPROFBUILDPATH;Percorso dell'eseguibile +PREFERENCES_CUSTPROFBUILD;Strumento per la generazione di profili su misura +PREFERENCES_CUTOVERLAYBRUSH;Tinta/opacità della maschera di ritaglio +PREFERENCES_DARKFRAMEFOUND;Presenti +PREFERENCES_DARKFRAMESHOTS;fotogrammi +PREFERENCES_DARKFRAMETEMPLATES;modelli +PREFERENCES_DARKFRAME;Calibrazione di fondo buio (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 +PREFERENCES_DEFAULTLANG;Lingua predefinita +PREFERENCES_DEFAULTTHEME;Aspetto ordinario +PREFERENCES_DEMOSAICINGALGO;Algoritmo di demosaicizzazione +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;Esegui altro da linea di comando +PREFERENCES_EDITORLAYOUT;Disposizione +PREFERENCES_EXTERNALEDITOR;Programmi di ritocco esterni +PREFERENCES_FBROWSEROPTS;Opzioni del navigatore di file +PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Barra di navigazione a singola fila (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;Calibrazione di campo piano (Flat-Field) +PREFERENCES_FORIMAGE;Per file di immagini +PREFERENCES_FORRAW;Per file di negativi RAW +PREFERENCES_GIMPPATH;Cartella d'installazione di GIMP +PREFERENCES_GTKTHEME;Predefinito GTK +PREFERENCES_HINT;Suggerimento +PREFERENCES_HISTOGRAMPOSITIONLEFT;Istogramma nel pannello sinistro +PREFERENCES_HLTHRESHOLD;Soglia per le alteluci tosate +PREFERENCES_ICCDIR;Cartella profili ICC +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 inclusa nel RAW, se mai sviluppato +PREFERENCES_LANGAUTODETECT;Usa l'impostazione di lingua del sistema +PREFERENCES_LIVETHUMBNAILS;Miniature sincronizzate (maggiore lentezza) +PREFERENCES_MENUGROUPFILEOPERATIONS;Raggruppa le operazioni sui file +PREFERENCES_MENUGROUPLABEL;Raggruppa le etichette +PREFERENCES_MENUGROUPPROFILEOPERATIONS;Raggruppa le operazioni sui profili +PREFERENCES_MENUGROUPRANK;Raggruppa le classificazioni +PREFERENCES_MENUOPTIONS;Opzioni del menù a discesa +PREFERENCES_METADATA;Metadati +PREFERENCES_MONITORICC;Profilo dello schermo +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_OUTDIRHINT;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'immagine finale in una cartella chiamata "/home/mario/foto/sviluppate/31-10-2010", scrivi:\n%p2/sviluppate/%d1/%f +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'immagine finale in una cartella chiamata "/home/mario/foto/sviluppate/31-10-2010", scrivi:\n%p2/sviluppate/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Segui lo schema +PREFERENCES_OUTDIR;Cartella di destinazione +PREFERENCES_OVERLAY_FILENAMES;Mostra i nomi dei file sovrapposti alle miniature +PREFERENCES_OVERWRITEOUTPUTFILE;Sovrascrivi file già 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 profili di elaborazione +PREFERENCES_PROFILELOADPR;Priorità nel caricamento del profilo +PREFERENCES_PROFILEPRCACHE;Profilo situato nella memoria del programma +PREFERENCES_PROFILEPRFILE;Profilo presente a fianco del file originario +PREFERENCES_PROFILESAVECACHE;Salva i parametri di elaborazione nella memoria del programma +PREFERENCES_PROFILESAVEINPUT;Salva i parametri di elaborazione a fianco del file originario +PREFERENCES_PROPERTY;Proprietà +PREFERENCES_PSPATH;Cartella d'installazione di Adobe Photoshop +PREFERENCES_SELECTFONT;Seleziona un carattere +PREFERENCES_SELECTICCDIRDLG;Seleziona la cartella dei profili ICC... +PREFERENCES_SELECTLANG;Seleziona la lingua +PREFERENCES_SELECTMONITORPROFDLG;Seleziona il profilo ICC dello schermo... +PREFERENCES_SELECTTHEME;Seleziona un tema +PREFERENCES_SET;IMPOSTA +PREFERENCES_SHOWBASICEXIF;Mostra dati Exif basilari +PREFERENCES_SHOWDATETIME;Mostra data e ora +PREFERENCES_SHOWONLYRAW;Mostra solo file RAW +PREFERENCES_SHOWPROFILESELECTOR;Mostra il selettore di profilo +PREFERENCES_SHTHRESHOLD;Soglia per le ombre tosate +PREFERENCES_SINGLETABVERTAB;Modalità a singola scheda, schede verticali +PREFERENCES_SINGLETAB;Modalità a singola scheda +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). Con Windows si può usare "SystemDefault", "SystemAsterisk" 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_OUTPUT;Opzioni di salvataggio +PREFERENCES_TAB_SOUND;Suoni +PREFERENCES_THUMBSIZE;Dimensione delle miniature +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_WORKFLOW;Flusso di lavoro +PROFILEPANEL_FILEDLGFILTERANY;Qualsiasi file +PROFILEPANEL_FILEDLGFILTERPP;Profili di sviluppo +PROFILEPANEL_LABEL;Profili di sviluppo +PROFILEPANEL_LOADDLGLABEL;Carico i parametri di sviluppo... +PROFILEPANEL_PCUSTOM;Personalizzato +PROFILEPANEL_PFILE;Da file +PROFILEPANEL_PLASTPHOTO;Ultima foto +PROFILEPANEL_PLASTSAVED;Ultimo salvato +PROFILEPANEL_PROFILE;Profilo +PROFILEPANEL_SAVEDLGLABEL;Salvo i parametri di sviluppo... +PROFILEPANEL_TOOLTIPCOPY;Copia il profilo corrente negli appunti +PROFILEPANEL_TOOLTIPLOAD;Carica profilo da file +PROFILEPANEL_TOOLTIPPASTE;Incolla il profilo dagli appunti +PROFILEPANEL_TOOLTIPSAVE;Salva il profilo corrente +PROGRESSBAR_BADPIXELS;Interpolazione pixel difettosi... +PROGRESSBAR_CACORRECTION;Correzione AC... +PROGRESSBAR_DARKFRAME;Applicazione Dark-Frame... +PROGRESSBAR_DECODING;Decodifica del file raw... +PROGRESSBAR_DEMOSAICING;Demosaicizzazione... +PROGRESSBAR_GREENEQUIL;Uniformazione del verde... +PROGRESSBAR_LINEDENOISE;Riduzione rumore a bande... +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_PROCESSING;Elaborazione dell'immagine... +PROGRESSBAR_READY;Pronto. +PROGRESSBAR_SAVEJPEG;Salvataggio del file JPEG... +PROGRESSBAR_SAVEPNG;Salvataggio del file PNG... +PROGRESSBAR_SAVETIFF;Salvataggio del file TIFF... +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profilo modificato nel navigatore +QINFO_FOCALLENGTH;Lunghezza focale +QINFO_ISO;ISO +QINFO_LENS;Obiettivo +QINFO_NOEXIF;Dati Exif non disponibili. +SAVEDLG_AUTOSUFFIX;Aggiungi automaticamente un suffisso se il file esiste già +SAVEDLG_FILEFORMAT;Formato file +SAVEDLG_JPEGQUAL;Qualità JPEG +SAVEDLG_JPGFILTER;file JPEG +SAVEDLG_PNGCOMPR;Compressione PNG +SAVEDLG_PNGFILTER;file 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_TIFFFILTER;file TIFF +SAVEDLG_TIFFUNCOMPRESSED;TIFF non compresso +TOOLBAR_TOOLTIP_CROP;Ritaglia selezione (scorciatoia: C) +TOOLBAR_TOOLTIP_HAND;Strumento mano (scorciatoia: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Seleziona una linea dritta (scorciatoia: S) +TOOLBAR_TOOLTIP_WB;Bilanciamento del bianco puntuale (scorciatoia: W) +TP_CACORRECTION_BLUE;Blu +TP_CACORRECTION_LABEL;Correzione aberrazioni cromatiche +TP_CACORRECTION_RED;Rosso +TP_CHMIXER_BLUE;Blu +TP_CHMIXER_GREEN;Verde +TP_CHMIXER_LABEL;Miscelatore canali +TP_CHMIXER_RED;Rosso +TP_CHROMATABERR_LABEL;Aberrazioni cromatiche +TP_COARSETRAF_DEGREE;Angolo: +TP_COARSETRAF_TOOLTIP_HFLIP;Rifletti orizzontalmente +TP_COARSETRAF_TOOLTIP_ROTLEFT;Ruota a sinistra +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Ruota a destra +TP_COARSETRAF_TOOLTIP_VFLIP;Rifletti verticalmente +TP_COLORBOOST_ACHANNEL;Canale "a" +TP_COLORBOOST_AMOUNT;Quantità +TP_COLORBOOST_AVOIDCOLORCLIP;Previeni tosaggio dei colori +TP_COLORBOOST_BCHANNEL;Canale "b" +TP_COLORBOOST_CHANNEL;Canale +TP_COLORBOOST_CHSEPARATE;separati +TP_COLORBOOST_ENABLESATLIMITER;Abilita limitatore di saturazione +TP_COLORBOOST_LABEL;Potenziamento colore +TP_COLORBOOST_SATLIMIT;Limite di saturazione +TP_COLORDENOISE_EDGESENSITIVE;Sensibile ai bordi +TP_COLORDENOISE_EDGETOLERANCE;Tolleranza bordi +TP_COLORDENOISE_LABEL;Riduzione Rumore di crominanza +TP_COLORDENOISE_RADIUS;Raggio +TP_COLORSHIFT_BLUEYELLOW;Blu-Giallo +TP_COLORSHIFT_GREENMAGENTA;Verde-Magenta +TP_COLORSHIFT_LABEL;Spostamento Colore +TP_CROP_FIXRATIO;Rapporto fisso: +TP_CROP_GTDIAGONALS;Regola delle diagonali +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;Fotogramma di fondo (Dark-Frame) +TP_DEFRINGE_LABEL;Rimozione aloni contrastati (PF) +TP_DEFRINGE_RADIUS;Raggio +TP_DEFRINGE_THRESHOLD;Soglia +TP_DETAIL_AMOUNT;Quantità +TP_DIRPYRDENOISE_CHROMA;Crominanza +TP_DIRPYRDENOISE_GAMMA;Gamma +TP_DIRPYRDENOISE_LABEL;Riduzione rumore +TP_DIRPYRDENOISE_LUMA;Luminanza +TP_DIRPYREQUALIZER_LABEL;Contrasto per livelli di dettaglio +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 (M4/3, alcune compatte, ecc.) +TP_DISTORTION_LABEL;Distorsione +TP_EQUALIZER_CONTRAST_MINUS;Contrasto- +TP_EQUALIZER_CONTRAST_PLUS;Contrasto+ +TP_EQUALIZER_FINEST;finissima +TP_EQUALIZER_LABEL;Equalizzatore Wavelet +TP_EQUALIZER_LARGEST;estesissima +TP_EQUALIZER_NEUTRAL;Neutro +TP_EXPOSCORR_LABEL;Esposizione +TP_EXPOSURE_AUTOLEVELS;Livelli automatici +TP_EXPOSURE_BLACKLEVEL;Livello del nero +TP_EXPOSURE_BRIGHTNESS;Luminosità +TP_EXPOSURE_CLIP;Tosa +TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Soglia di recupero alteluci +TP_EXPOSURE_COMPRHIGHLIGHTS;Recupero alteluci +TP_EXPOSURE_COMPRSHADOWS;Recupero ombre +TP_EXPOSURE_CONTRAST;Contrasto +TP_EXPOSURE_CURVEEDITOR;Curva di tono +TP_EXPOSURE_EXPCOMP;Compensazione esposizione +TP_EXPOSURE_LABEL;Esposizione +TP_EXPOSURE_SATURATION;Saturazione +TP_EXPO_AFTER; Dopo l'interpolazione (prima della conversione RGB) +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;Fotogramma di campo (Flat-Field) +TP_GAMMA_CURV;gamma +TP_GAMMA_FREE;Gamma libero +TP_GAMMA_OUTPUT;Punto del gamma a posteriori +TP_GAMMA_SLOP;pendenza (lineare) +TP_HLREC_BLEND;Fusione +TP_HLREC_CIELAB;Miscelazione in CIELab +TP_HLREC_COLOR;Propagazione di crominanza +TP_HLREC_LABEL;Ricostruzione alteluci +TP_HLREC_LUMINANCE;Recupero di luminanza +TP_HLREC_METHOD;Metodo: +TP_HSVEQUALIZER1;Rosso +TP_HSVEQUALIZER2;Giallo +TP_HSVEQUALIZER3;Lime +TP_HSVEQUALIZER4;Verde +TP_HSVEQUALIZER5;Ciano +TP_HSVEQUALIZER6;Blu +TP_HSVEQUALIZER7;Viola +TP_HSVEQUALIZER8;Magenta +TP_HSVEQUALIZER_CHANNEL;Canale HSV +TP_HSVEQUALIZER_HUE;H +TP_HSVEQUALIZER_LABEL;Equalizzatore HSV +TP_HSVEQUALIZER_NEUTRAL;Neutro +TP_HSVEQUALIZER_SAT;S +TP_HSVEQUALIZER_VAL;V +TP_ICM_FILEDLGFILTERANY;Qualsiasi file +TP_ICM_FILEDLGFILTERICM;File profili ICC +TP_ICM_GAMMABEFOREINPUT;Il profilo applica il Gamma +TP_ICM_INPUTCAMERAICC;Predefinito della fotocamera o ICC +TP_ICM_INPUTCAMERA;Predefinito della fotocamera +TP_ICM_INPUTCUSTOM;Personalizzato +TP_ICM_INPUTDLGLABEL;Seleziona il profilo ICC di ingresso... +TP_ICM_INPUTEMBEDDED;Incorporato, se disponibile +TP_ICM_INPUTNONE;Nessun profilo +TP_ICM_INPUTPROFILE;Profilo di ingresso +TP_ICM_LABEL;ICM +TP_ICM_NOICM;Nessun ICM: uscita in sRGB +TP_ICM_OUTPUTDLGLABEL;Seleziona il profilo ICC di uscita... +TP_ICM_OUTPUTPROFILE;Profilo di Uscita +TP_ICM_SAVEREFERENCE;Salva riferimento per la profilazione +TP_ICM_WORKINGPROFILE;Profilo di Lavoro +TP_IMPULSEDENOISE_LABEL;Riduzione rumore puntuale +TP_IMPULSEDENOISE_THRESH;Soglia RR puntuale +TP_LABCURVE_AVOIDCOLORCLIP;Previeni tosaggio dei colori +TP_LABCURVE_BRIGHTNESS;Luminosità +TP_LABCURVE_CONTRAST;Contrasto +TP_LABCURVE_CURVEEDITOR;Curva di luminanza +TP_LABCURVE_ENABLESATLIMITER;Abilita limitatore della saturazione +TP_LABCURVE_LABEL;Regolazioni Lab +TP_LABCURVE_SATLIMIT;Limite di saturazione +TP_LABCURVE_SATURATION;Saturazione +TP_LENSGEOM_AUTOCROP; Ritaglio automatico +TP_LENSGEOM_FILL;Riadatta +TP_LENSGEOM_LABEL;Obiettivo / Geometria +TP_LUMADENOISE_EDGETOLERANCE;Tolleranza bordi +TP_LUMADENOISE_LABEL;Riduzione rumore di luminanza +TP_LUMADENOISE_RADIUS;Raggio +TP_PERSPECTIVE_HORIZONTAL;Orizzontale +TP_PERSPECTIVE_LABEL;Prospettiva +TP_PERSPECTIVE_VERTICAL;Verticale +TP_PREPROCESS_GREENEQUIL;Uniformazione del verde +TP_PREPROCESS_HOTDEADPIXFILT;Interpola 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;Effettua la fase di affinamento per DCB +TP_RAW_DCBITERATIONS;Numero di iterazioni DCB +TP_RAW_DMETHOD;Metodo +TP_RAW_FALSECOLOR;Stadi per soppressione di falsi colori +TP_RAW_LABEL;Demosaicizzazione +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_DOWNSCALEB;Riduzione (più accurata) +TP_RESIZE_DOWNSCALEF;Riduzione (più rapida) +TP_RESIZE_FITBOX;Riquadro delimitato +TP_RESIZE_FULLIMAGE;Tutta l'immagine +TP_RESIZE_FULLSIZE;Dimensione dell'intera 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_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 +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_USM;Maschera di contrasto +TP_SHARPENMICRO_AMOUNT;Quantità +TP_SHARPENMICRO_LABEL;Microcontrasto +TP_SHARPENMICRO_MATRIX;Matrice 3×3 invece di 5×5 +TP_SHARPENMICRO_UNIFORMITY;Uniformità +TP_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;Potenza +TP_WBALANCE_AUTO;Automatico +TP_WBALANCE_CAMERA;Fotocamera +TP_WBALANCE_CUSTOM;Personalizzato +TP_WBALANCE_GREEN;Tinta +TP_WBALANCE_LABEL;Bilanciamento del bianco +TP_WBALANCE_METHOD;Metodo +TP_WBALANCE_SIZE;Dimensione: +TP_WBALANCE_SPOTWB;Punto BB manuale +TP_WBALANCE_TEMPERATURE;Temperatura +ZOOMBAR_DETAIL;Dettaglio +ZOOMBAR_HUGE;Enorme +ZOOMBAR_LARGE;Grande +ZOOMBAR_NORMAL;Normale +ZOOMBAR_PREVIEW;Anteprima +ZOOMBAR_SCALE;Scala +ZOOMBAR_SMALL;Piccola +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;Apri (nuova) finestra di dettaglio +ZOOMPANEL_ZOOM100;Ingrandimento al 100% (scorciatoia: 1) +ZOOMPANEL_ZOOMFITSCREEN;Adatta allo schermo (scorciatoia: F) +ZOOMPANEL_ZOOMIN;Ingrandisci (scorciatoia: +) +ZOOMPANEL_ZOOMOUT;Rimpicciolisci (scorciatoia: -) + +#00 Italian +#01 UTF-8(unix mode) +#02 19-01-2008 v2.3 breek +#03 01-11-2008 v2.4 pantaraf, chelidon, roberto +#04 26-08-2011 v3.0 joker, chelidon, ffsup2 +#05 31-08-2011 v4.0 chelidon, ffsup2 +#06 Inserire una nota con la data ad ogni modifica per maggiore chiarezza. +#07 IMPORTANTE: Contribuisci sul forum di rawtherapee nella pagina di localizzazione italiana se trovi errori http://www.rawtherapee.com/forum/viewtopic.php?p=3354 + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!ABOUT_TAB_RELEASENOTES;Release Notes +!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_SHARPENEDGE;Bypass Edge Sharpening +!EXPORT_BYPASS_SHARPENING;Bypass Sharpening +!EXPORT_BYPASS_SHARPENMICRO;Bypass Microcontrast +!EXPORT_BYPASS_SH_HQ;Bypass Shadow/Highlights (High Quality) +!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_EXTPROGMENU;Open with +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!FILEBROWSER_POPUPPROCESSFAST;Put to Queue (Fast export) +!GENERAL_WARNING;Warning +!HISTOGRAM_TOOLTIP_FULL;Toggle full or scaled histogram +!HISTORY_MSG_117;Red CA Correction +!HISTORY_MSG_151;Vibrance +!HISTORY_MSG_152;Vibrance - Pastel tones +!HISTORY_MSG_153;Vibrance - Saturated tones +!HISTORY_MSG_154;Vibrance - Protect skin tones +!HISTORY_MSG_155;Vibrance - Avoid color drift +!HISTORY_MSG_156;Vibrance - Link pastel and saturated tones +!HISTORY_MSG_157;Vibrance - Pastel/Saturated threshold +!HISTORY_MSG_158;Strength +!HISTORY_MSG_159;Edge Stopping +!HISTORY_MSG_160;Scale +!HISTORY_MSG_161;Reweighting Iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_163;RGB Curves - R +!HISTORY_MSG_164;RGB Curves - G +!HISTORY_MSG_165;RGB Curves - B +!HISTORY_MSG_166;Neutral Levels +!HISTORY_MSG_167;B&W Toning +!HISTORY_MSG_168;'Cc' curve +!HISTORY_MSG_169;'Ch' curve +!HISTORY_MSG_170;Vibrance - Curve +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue processed first. +!MAIN_TAB_EXPORT; Export +!MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 8 +!MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 0 +!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_EPD;Tone Mapping +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_RGBCURVES;RGB curves +!PARTIALPASTE_VIBRANCE;Vibrance +!PREFERENCES_MENUGROUPEXTPROGS;Group "Open with" +!PREFERENCES_SHOWEXPOSURECOMPENSATION;Append exposure compensation +!PREFERENCES_TP_LABEL;Tool panel: +!PREFERENCES_TP_USEICONORTEXT;Use tab icons instead of text +!PREFERENCES_TP_VSCROLLBAR;Hide vertical scrollbar +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_SAVEPPASTE;Parameters to save +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing Profile Saved +!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\nthe 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_CROP_GTEPASSPORT;Biometric Passport +!TP_CROP_GTFRAME;Frame +!TP_EPD_EDGESTOPPING;Edge stopping +!TP_EPD_LABEL;Tone Mapping +!TP_EPD_REWEIGHTINGITERATES;Reweighting iterates +!TP_EPD_SCALE;Scale +!TP_EPD_STRENGTH;Strength +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggle execution of Auto Levels to automatically set parameter values based on image analysis +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in auto levels operation +!TP_ICM_BLENDCMSMATRIX;Blend highlights with matrix +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover blown highlights when using LUT based ICC profiles +!TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profile. These profiles are more precise than simpler matrix ones. Available for some 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_PREFERREDPROFILE;Preferred DCP profile +!TP_ICM_PREFERREDPROFILE_1;Daylight +!TP_ICM_PREFERREDPROFILE_2;Tungsten +!TP_ICM_PREFERREDPROFILE_3;Fluorescent +!TP_ICM_PREFERREDPROFILE_4;Flash +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid Color Shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space\nand apply Munsell correction +!TP_LABCURVE_BWTONING;B&W Toning +!TP_LABCURVE_BWTONING_TIP;With B&W Toning option enabled, the Lab Chromaticity, Cc and Ch curves are not in effect.\nToning can be achieved using the a and b curves +!TP_LABCURVE_CHROMATICITY;Chromaticity +!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 the Chromaticity +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to the Hue +!TP_LABCURVE_RSTPROTECTION;Red and Skin Tones Protection +!TP_LENSPROFILE_FILEDLGFILTERLCP;Lens correction files +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;Use CA correction +!TP_LENSPROFILE_USEDIST;Use distortion correction +!TP_LENSPROFILE_USEVIGN;Use vignette correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset exposure controls to neutral values +!TP_PREPROCESS_HOTDEADPIXTHRESH;Hot/dead pixel detection threshold +!TP_RGBCURVES_BLUE;B +!TP_RGBCURVES_CHANNEL;Channel +!TP_RGBCURVES_GREEN;G +!TP_RGBCURVES_LABEL;RGB Curves +!TP_RGBCURVES_RED;R +!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 the Hue +!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_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 diff --git a/rtdata/languages/Japanese b/rtdata/languages/Japanese new file mode 100644 index 000000000..90f6bd082 --- /dev/null +++ b/rtdata/languages/Japanese @@ -0,0 +1,1228 @@ +ABOUT_TAB_BUILD;ヴァージョン +ABOUT_TAB_CREDITS;クレジット +ABOUT_TAB_LICENSE;ライセンス +ABOUT_TAB_RELEASENOTES;リリースノート +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_DIALOGLABEL;Exif情報 +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_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_ARRANGEMENTHINT;サムネイル整列 縦/横 +FILEBROWSER_AUTODARKFRAME;オート・ダークフレーム +FILEBROWSER_AUTOFLATFIELD;オート・フラットフィールド +FILEBROWSER_BROWSEPATHBUTTONHINT;クリックで選択したパスをブラウズ +FILEBROWSER_BROWSEPATHHINT;参照するパスを入力します\nCtrl-o パスのテキストボックスにフォーカス\nEnter / Ctrl-Enter(ファイルブラウザで)その場所をブラウズします;\nパスのショートカット:\n ~ - ユーザーのホームディレクトリ\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_EXIFFILTERAPPLYHINT;Exifフィルタのon/off ファイルブラウザの切り替え +FILEBROWSER_EXIFFILTERAPPLY;適用 +FILEBROWSER_EXIFFILTERLABEL;Exifフィルタ +FILEBROWSER_EXIFFILTERSETTINGSHINT;Exifフィルタの設定を変える +FILEBROWSER_EXIFFILTERSETTINGS;セットアップ +FILEBROWSER_EXTPROGMENU;..で開く +FILEBROWSER_FLATFIELD;フラットフィールド +FILEBROWSER_MOVETODARKFDIR;ダークフレーム・ディレクトリに移動 +FILEBROWSER_MOVETOFLATFIELDDIR;フラットフィールド・ディレクトリに移動 +FILEBROWSER_NEW_NAME;新規名称: +FILEBROWSER_OPENDEFAULTVIEWER;Windowsのデフォルト・ビューア(キュー処理) +FILEBROWSER_PARTIALPASTEPROFILE;部分的に貼り付け +FILEBROWSER_PASTEPROFILE;プロファイルの貼り付け +FILEBROWSER_POPUPCANCELJOB;ジョブ キャンセル +FILEBROWSER_POPUPCOLORLABEL0;ラベル: なし +FILEBROWSER_POPUPCOLORLABEL1;ラベル: レッド +FILEBROWSER_POPUPCOLORLABEL2;ラベル: イエロー +FILEBROWSER_POPUPCOLORLABEL3;ラベル: グリーン +FILEBROWSER_POPUPCOLORLABEL4;ラベル: ブルー +FILEBROWSER_POPUPCOLORLABEL5;ラベル: パープル +FILEBROWSER_POPUPCOLORLABEL;カラー・ラベル +FILEBROWSER_POPUPCOPYTO;コピーします... +FILEBROWSER_POPUPFILEOPERATIONS;ファイルの操作 +FILEBROWSER_POPUPMOVEEND;キュー処理の最後に移動 +FILEBROWSER_POPUPMOVEHEAD;キュー処理の最初に移動 +FILEBROWSER_POPUPMOVETO;移動します... +FILEBROWSER_POPUPOPEN;開く +FILEBROWSER_POPUPPROCESSFAST;キューに追加 (高速書き出し) +FILEBROWSER_POPUPPROCESS;キューに追加 +FILEBROWSER_POPUPPROFILEOPERATIONS;プロファイルの操作 +FILEBROWSER_POPUPRANK1;ランク 1 * +FILEBROWSER_POPUPRANK2;ランク 2 ** +FILEBROWSER_POPUPRANK3;ランク 3 *** +FILEBROWSER_POPUPRANK4;ランク 4 **** +FILEBROWSER_POPUPRANK5;ランク 5 ***** +FILEBROWSER_POPUPRANK;ランク +FILEBROWSER_POPUPREMOVEINCLPROC;ファイルシステムとバッチの結果から削除 +FILEBROWSER_POPUPREMOVESUBMENU;削除 +FILEBROWSER_POPUPREMOVE;ファイルシステムから削除 +FILEBROWSER_POPUPRENAME;名前変更 +FILEBROWSER_POPUPSELECTALL;全選択 +FILEBROWSER_POPUPTRASH;ゴミ箱へ移動 +FILEBROWSER_POPUPUNRANK;ランクなし +FILEBROWSER_POPUPUNTRASH;ゴミ箱から移動 +FILEBROWSER_PROCESSINGSETTINGSHINT;ファイル形式と出力ディレクトリを設定 +FILEBROWSER_PROCESSINGSETTINGS;設定 +FILEBROWSER_QUERYBUTTONHINT;検索クエリをクリア +FILEBROWSER_QUERYHINT;検索するファイル名の一部を入力します\nCtrl-f 検索テキストボックスにフォーカス(ファイルブラウザで);\nEnter 検索を開始します +FILEBROWSER_QUERYLABEL; 検索: +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 +FILEBROWSER_SHOWQUEUEHINT;処理するキューの内容を表示 +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-` +FILEBROWSER_SHOWUNRANKHINT;ランクなし画像を表示\nショートカット: ` +FILEBROWSER_STARTPROCESSINGHINT;処理開始/キュー画像の保存 +FILEBROWSER_STARTPROCESSING;処理開始 +FILEBROWSER_STOPPROCESSINGHINT;画像処理の中止 +FILEBROWSER_STOPPROCESSING;処理中止 +FILEBROWSER_THUMBSIZE;サムネイル.サイズ +FILEBROWSER_TOOLTIP_STOPPROCESSING;新しいジョブがきたら自動的に処理を開始します +FILEBROWSER_USETEMPLATE;テンプレート使用: +FILEBROWSER_ZOOMINHINT;サムネイルサイズの拡大\nショートカット: + +FILEBROWSER_ZOOMOUTHINT;サムネイルサイズの縮小\nショートカット: - +GENERAL_ABOUT;RawTherapeeについて.. +GENERAL_AFTER;補正後 +GENERAL_BEFORE;補正前 +GENERAL_CANCEL;キャンセル +GENERAL_DISABLED;無効 +GENERAL_DISABLE;無効 +GENERAL_ENABLED;有効 +GENERAL_ENABLE;有効 +GENERAL_FILE;ファイル +GENERAL_HIGH_QUALITY;高画質 +GENERAL_LANDSCAPE;横 +GENERAL_LOAD;読み込み +GENERAL_NA;n/a +GENERAL_NONE;なし +GENERAL_NO;No +GENERAL_OK;OK +GENERAL_PORTRAIT;縦 +GENERAL_SAVE;保存 +GENERAL_UNCHANGED;(変更なし) +GENERAL_WARNING;警告 +GENERAL_YES;Yes +HISTOGRAM_BUTTON_BAR;RGB +HISTOGRAM_BUTTON_B;B +HISTOGRAM_BUTTON_G;G +HISTOGRAM_BUTTON_L;L +HISTOGRAM_BUTTON_RAW;Raw +HISTOGRAM_BUTTON_R;R +HISTOGRAM_LABEL;ヒストグラム +HISTOGRAM_TOOLTIP_BAR;RBG インジケーター・バーの表示/非表示\nプレビュー画像上でマウスの右ボタンクリックで 固定/開放 +HISTOGRAM_TOOLTIP_B;ブルー・ヒストグラム 表示/非表示 +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;トーンカーブ +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;RL デコンボリューション 半径 +HISTORY_MSG_31;RL デコンボリューション 適用量 +HISTORY_MSG_32;RL デコンボリューション 減衰 +HISTORY_MSG_33;RL デコンボリューション 繰返し +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;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;ウェーブレット イコライザ +HISTORY_MSG_87;インパルス ノイズ低減 +HISTORY_MSG_88;インパルス NR しきい値 +HISTORY_MSG_89;ノイズ低減 +HISTORY_MSG_90;NR - 輝度 +HISTORY_MSG_91;NR - カラー +HISTORY_MSG_92;NR - ガンマ +HISTORY_MSG_93;ディテールのコントラスト係数 +HISTORY_MSG_94;ディテールのコントラスト +HISTORY_MSG_95;彩度 +HISTORY_MSG_96;'a' カーブ +HISTORY_MSG_97;'b' カーブ +HISTORY_MSG_98;デモザイク +HISTORY_MSG_99;前処理 +HISTORY_MSG_100;RGB 彩度 +HISTORY_MSG_101;HSV EQ -- 色相 +HISTORY_MSG_102;HSV EQ -- 彩度 +HISTORY_MSG_103;HSV EQ -- 明度 +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;カラークリッピング回避 +HISTORY_MSG_112;彩度制限 +HISTORY_MSG_113;彩度の制限 +HISTORY_MSG_114;DCB反復 +HISTORY_MSG_115;偽色抑制 +HISTORY_MSG_116;DCB拡張 +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;露光補正 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 カーブ - R +HISTORY_MSG_164;RGB カーブ - G +HISTORY_MSG_165;RGB カーブ - B +HISTORY_MSG_166;ニュートラル・レベル +HISTORY_MSG_167;白黒トーン +HISTORY_NEWSNAPSHOTAS;ラベル +HISTORY_NEWSNAPSHOT;追加 +HISTORY_NEWSSDIALOGLABEL;スナップのラベル: +HISTORY_NEWSSDIALOGTITLE;新規スナップ追加 +HISTORY_SETTO;設定: +HISTORY_SNAPSHOTS;スナップショット +HISTORY_SNAPSHOT;スナップショット +ICMPANEL_FILEDLGFILTERANY;すべてのファイル +ICMPANEL_FILEDLGFILTERICM;ICCプロファイル ファイル +ICMPANEL_GAMMABEFOREINPUT;プロファイルにガンマ適用 +ICMPANEL_INPUTCAMERA;カメラの既定値 +ICMPANEL_INPUTCUSTOM;カスタム +ICMPANEL_INPUTDLGLABEL;入力 ICC プロファイルを選択... +ICMPANEL_INPUTEMBEDDED;埋め込み使用, 可能なら +ICMPANEL_INPUTPROFILE;入力プロファイル +ICMPANEL_NOICM;No ICM: sRGB 出力 +ICMPANEL_OUTPUTDLGLABEL;出力 ICC プロファイルを選択... +ICMPANEL_OUTPUTPROFILE;出力プロファイル +ICMPANEL_SAVEREFERENCE;プロファイリングの参照する画像を保存 +ICMPANEL_WORKINGPROFILE;作業プロファイル +IMAGEAREA_DETAILVIEW;ディテール +IPTCPANEL_AUTHORHINT;作成者の名前、作家、カメラマンまたはグラフィックスアーティスト(署名). +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_EXIT;終了 +MAIN_BUTTON_FULLSCREEN;フルスクリーン +MAIN_BUTTON_PREFERENCES;環境設定 +MAIN_BUTTON_PUTTOQUEUE;キューに追加 +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;現在の画像をキュー処理に追加\nショートカット: Ctrl+Q +MAIN_BUTTON_QUEUE;キューに追加 +MAIN_BUTTON_SAVE;画像の保存 +MAIN_BUTTON_SAVE_TOOLTIP;現在の画像を保存\nショートカット: Ctrl+S +MAIN_BUTTON_SENDTOEDITOR;エディタに送る +MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;現在の画像を外部エディタで編集\nショートカット: Ctrl+E +MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;表示/非表示 すべてのパネル\nショートカット: m +MAIN_BUTTON_UNFULLSCREEN;フルスクリーン解除 +MAIN_FRAME_BATCHQUEUE;キュー +MAIN_FRAME_BATCHQUEUE_TOOLTIP;キューで処理します\nショートカット: Ctrl-F3 +MAIN_FRAME_EDITOR;編集 +MAIN_FRAME_EDITOR_TOOLTIP; 編集\nショートカット: Ctrl-F4 +MAIN_FRAME_FILEBROWSER;ファイルブラウザ +MAIN_FRAME_FILEBROWSER_TOOLTIP; ファイル・ブラウザ\nショートカット: Ctrl-F2 +MAIN_FRAME_PLACES;場所 +MAIN_FRAME_PLACES_ADD;追加 +MAIN_FRAME_PLACES_DEL;削除 +MAIN_FRAME_RECENT;最近開いたフォルダ +MAIN_MSG_ALREADYEXISTS;ファイルはすでに存在します +MAIN_MSG_CANNOTLOAD;画像読み込みできません +MAIN_MSG_CANNOTSAVE;ファイル保存エラー +MAIN_MSG_CANNOTSTARTEDITOR;エディタを開始することができません +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;"環境設定"で正しいパスを設定してください +MAIN_MSG_EMPTYFILENAME;未定義のファイル名 +MAIN_MSG_ERRORDURINGIMAGESAVING;画像の保存中にエラー +MAIN_MSG_EXITJOBSINQUEUEINFO;未処理画像の順番は終了時に失われます +MAIN_MSG_EXITJOBSINQUEUEQUEST;キュー待ちの画像がありますが、終了しますか? +MAIN_MSG_IMAGEUNPROCESSED;このコマンドは、先に選択されたすべての画像をキュー処理する必要があります。 +MAIN_MSG_JOBSINQUEUE; キューの作業中・・・ +MAIN_MSG_NAVIGATOR;ナビゲータ +MAIN_MSG_PLACES;場所 +MAIN_MSG_QOVERWRITE;上書きしますか? +MAIN_TAB_BASIC;ベーシック +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_ICM;ICM +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_TOGGLE_BEFORE_AFTER;補正 前|後 +MAIN_TOOLTIP_BACKCOLOR0;プレビューの背景色を指定します: テーマに基づく\nショートカット: 8 +MAIN_TOOLTIP_BACKCOLOR1;プレビューの背景色を指定します: \nショートカットt: 9 +MAIN_TOOLTIP_BACKCOLOR2;プレビューの背景色を指定します: \nショートカット: 0 +MAIN_TOOLTIP_BEFOREAFTERLOCK;固定 / 固定解除 - 補正前 の表示設定\n\n固定: 補正前をそのまま表示し変更されません。\n複数のツールの累積効果を評価するのに役立ちます。\nさらに、比較は履歴上のどこからでも行うことができます。\n\n固定解除: 現在使用のツールの効果が 補正後 に表示され、その1段階前が 補正前 に表示されます。 +MAIN_TOOLTIP_HIDEFP;ボタンパネル 表示/非表示(ディレクトリとファイルブラウザ)\nショートカット: F +MAIN_TOOLTIP_HIDEHP;左パネル 表示/非表示 (履歴含む)\nショートカット: l +MAIN_TOOLTIP_INDCLIPPEDH;ハイライト・クリッピング領域の表示\nショートカット: < +MAIN_TOOLTIP_INDCLIPPEDS;シャドウ・クリッピング領域の表示\nショートカット: > +MAIN_TOOLTIP_PREFERENCES;設定する +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_SAVEAS;フォルダを選択して保存 +MAIN_TOOLTIP_SAVE;デフォルトのフォルダに保存 +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_CHANNELMIXER;チャンネル・ミキサー +PARTIALPASTE_COARSETRANS;90° 回転 / 反転 +PARTIALPASTE_COLORBOOST;発色補正 +PARTIALPASTE_COLORDENOISE;カラー ノイズ低減 +PARTIALPASTE_COLORGROUP;カラー 設定 +PARTIALPASTE_COLORMIXER;カラー ミキサー +PARTIALPASTE_COLORSHIFT;カラー シフト +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;FF 自動選択 +PARTIALPASTE_FLATFIELDBLURRADIUS;FF ぼかし半径 +PARTIALPASTE_FLATFIELDBLURTYPE;FF ぼかしタイプ +PARTIALPASTE_FLATFIELDFILE;フラットフィールド (FF) ファイル +PARTIALPASTE_HLRECONSTRUCTION;ハイライト復元 +PARTIALPASTE_HLRECOVERYAMOUNT;ハイライト復元 適用量 +PARTIALPASTE_HLRECOVERYTHRESHOLD;ハイライト復元 しきい値 +PARTIALPASTE_HLRECOVERY;ハイライト復元 +PARTIALPASTE_HSVEQUALIZER;HSV イコライザ +PARTIALPASTE_ICMGAMMA;出力ガンマ +PARTIALPASTE_ICMSETTINGS;ICM 設定 +PARTIALPASTE_IMPULSEDENOISE;インパルス・ノイズ低減 +PARTIALPASTE_IPTCINFO;IPTC 情報 +PARTIALPASTE_LABCURVE;Lab 調整 +PARTIALPASTE_LENSGROUP;レンズ設定 +PARTIALPASTE_LUMADENOISE;輝度 ノイズ低減 +PARTIALPASTE_LUMINANCEGROUP;輝度設定 +PARTIALPASTE_METAICMGROUP;メタデータ/ICM 設定 +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_RESIZE;リサイズ +PARTIALPASTE_RGBCURVES;RGB カーブ +PARTIALPASTE_ROTATION;回転 +PARTIALPASTE_SHADOWSHIGHLIGHTS;シャドウ/ハイライト +PARTIALPASTE_SHARPENEDGE;エッジ +PARTIALPASTE_SHARPENING;シャープ化 (USM/RL) +PARTIALPASTE_SHARPENMICRO;マイクロコントラスト +PARTIALPASTE_VIBRANCE;自然な彩度 +PARTIALPASTE_VIGNETTING;周辺光量補正 +PARTIALPASTE_WAVELETEQUALIZER;ウェーブレット・イコライザ +PARTIALPASTE_WHITEBALANCE;ホワイトバランス +PREFERENCES_ADD;追加 +PREFERENCES_APPLNEXTSTARTUP;要再起動 +PREFERENCES_AUTOMONPROFILE;自動的にOSのメインモニター・プロファイルを使用 +PREFERENCES_BATCH_PROCESSING;バッチ処理 +PREFERENCES_BEHAVIOR;ビヘイビア +PREFERENCES_BLINKCLIPPED;クリッピング領域の点滅 +PREFERENCES_CABLUE;色収差 ブルー 手動補正 +PREFERENCES_CACHECLEARALL;すべてクリア +PREFERENCES_CACHECLEARPROFILES;プロファイルのクリア +PREFERENCES_CACHECLEARTHUMBS;サムネイルのクリア +PREFERENCES_CACHEFORMAT1;独自仕様 (速く 良質) +PREFERENCES_CACHEFORMAT2;JPEG (少ないディスク占有) +PREFERENCES_CACHEMAXENTRIES;最大キャッシュエントリー数 +PREFERENCES_CACHEOPTS;キャッシュ オプション +PREFERENCES_CACHESTRAT1;スピード重視 +PREFERENCES_CACHESTRAT2;メモリ消費重視 +PREFERENCES_CACHESTRAT;キャッシュ運用の方針 +PREFERENCES_CACHETHUMBFORM;キャッシュのサムネイル形式 +PREFERENCES_CACHETHUMBHEIGHT;サムネイル縦の最大値 +PREFERENCES_CACORRECTION;色収差補正を適用 +PREFERENCES_CARED;色収差 レッド 手動補正 +PREFERENCES_CLIPPINGIND;クリッピング領域の表示 +PREFERENCES_CMETRICINTENT;レンダリング・インテント +PREFERENCES_CUSTPROFBUILDHINT;画像から新規のプロファイルを作成する際に呼び出される実行ファイル (またはスクリプト)\n.PP3生成のルールに基づいたコマンドライン・パラメータを受け取ります。\n[raw/JPG・パス] [デフォルトのプロファイルのパス] [f-数値] [露出時間 秒] [焦点距離 mm] [ISO] [レンズ] [カメラ] +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%y/%m/%d +PREFERENCES_DATEFORMAT;日付の形式 +PREFERENCES_DCBENHANCE;DCB拡張処置の適用 +PREFERENCES_DCBITERATIONS;DCB反復の数 +PREFERENCES_DEFAULTLANG;デフォルトの言語 +PREFERENCES_DEFAULTTHEME;デフォルト テーマ +PREFERENCES_DEMOSAICINGALGO;デモザイク処理 +PREFERENCES_DIRDARKFRAMES;ダークフレーム・ディレクトリ +PREFERENCES_DIRHOME;ホーム・ディレクトリ +PREFERENCES_DIRLAST;最近参照したディレクトリ +PREFERENCES_DIROTHER;他 +PREFERENCES_DIRSELECTDLG;起動時の画像・ディレクトリ選択... +PREFERENCES_DIRSOFTWARE;インストール・ディレクトリ +PREFERENCES_DMETHODBATCH;バッチ +PREFERENCES_DMETHOD;方法 +PREFERENCES_EDITORCMDLINE;その他・コマンド入力 +PREFERENCES_EDITORLAYOUT;編集 レイアウト +PREFERENCES_EXPOS;補間前露光 :補正 (lin) +PREFERENCES_EXTERNALEDITOR;外部エディタ +PREFERENCES_FALSECOLOR;偽色 補間処理 +PREFERENCES_FBROWSEROPTS;ファイルブラウザのオプション +PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;ファイルブラウザでの一行のツールバー (低解像度表示用に選択解除) +PREFERENCES_FILEFORMAT;ファイル形式 +PREFERENCES_FLATFIELDAUTOSELECT;フラットフィールド自動選択 +PREFERENCES_FLATFIELDBLURRADIUS;フラットフィールド・ぼかし半径 +PREFERENCES_FLATFIELDBLURTYPE;フラットフィールド・ぼかしタイプ +PREFERENCES_FLATFIELDFILE;フラットフィールド +PREFERENCES_FLATFIELDFOUND;検出 +PREFERENCES_FLATFIELDSDIR;フラットフィールド・ディレクトリ +PREFERENCES_FLATFIELDSHOTS;ショット +PREFERENCES_FLATFIELDTEMPLATES;テンプレート +PREFERENCES_FLATFIELD;フラットフィールド +PREFERENCES_FORIMAGE;画像ファイル +PREFERENCES_FORRAW;RAW ファイル +PREFERENCES_GIMPPATH;GIMP インストール ディレクトリ +PREFERENCES_GREENEQUIL;グリーン 平衡化 +PREFERENCES_GTKTHEME;GTK デフォルト +PREFERENCES_HINT;ヒント +PREFERENCES_HISTOGRAMPOSITIONLEFT;左パネルにヒストグラム +PREFERENCES_HLTHRESHOLD;ハイライト・クリッピング領域のしきい値 +PREFERENCES_HOTDEADPIXFILT;ホット/デッド ピクセル・フィルタを適用 +PREFERENCES_ICCDIR;ICCプロファイルのディレクトリ +PREFERENCES_IMPROCPARAMS;画像処理の既定値 +PREFERENCES_INTENT_ABSOLUTE;絶対的な色域を維持 +PREFERENCES_INTENT_PERCEPTUAL;知覚的 +PREFERENCES_INTENT_RELATIVE;相対的な色域を維持 +PREFERENCES_INTENT_SATURATION;彩度 +PREFERENCES_INTERNALTHUMBIFUNTOUCHED;未編集の場合 内部のRAWサムネイルを表示 +PREFERENCES_LANGAUTODETECT;OSの言語設定を使用 +PREFERENCES_LINEDENOISE;ラインノイズ フィルタ +PREFERENCES_LIVETHUMBNAILS;ライブ・サムネイル (遅い) +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_OUTDIRHINT;次の書式文字を使用することができます:\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_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_PRESER;補間前露光 :ハイライト保護 (EV) +PREFERENCES_PROFILEHANDLING;処理プロファイルの取扱い +PREFERENCES_PROFILELOADPR;プロファイル読み込みの優先権 +PREFERENCES_PROFILEPRCACHE;キャッシュのプロファイル +PREFERENCES_PROFILEPRFILE;入力ファイル・ディレクトリのプロファイル +PREFERENCES_PROFILESAVECACHE;後処理プロファイルのパラメータをキャッシュに保存 +PREFERENCES_PROFILESAVEINPUT;後処理プロファイルのパラメータを入力ファイルと同じディレクトリに保存 +PREFERENCES_PROPERTY;プロパティ +PREFERENCES_PSPATH;Adobe Photoshop のインストール・ディレクトリ +PREFERENCES_SELECTFONT;フォント選択 +PREFERENCES_SELECTICCDIRDLG;ICCプロファイル・ディレクトリ選択... +PREFERENCES_SELECTLANG;言語選択 +PREFERENCES_SELECTMONITORPROFDLG;ディスプレイのICCプロファイルを選択... +PREFERENCES_SELECTTHEME;選択 テーマ +PREFERENCES_SET;セット +PREFERENCES_SHOWBASICEXIF;基本Exif情報 表示 +PREFERENCES_SHOWDATETIME;日付表示 +PREFERENCES_SHOWEXPOSURECOMPENSATION;露光補正追加 +PREFERENCES_SHOWONLYRAW;RAWファイルのみ表示 +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_OUTPUT;出力オプション +PREFERENCES_TAB_SOUND;サウンド +PREFERENCES_THUMBSIZE;サムネイル・サイズ +PREFERENCES_TP_LABEL;ツール パネル: +PREFERENCES_TP_USEICONORTEXT;テキストの代わりにタブアイコンを使用 +PREFERENCES_TP_VSCROLLBAR;ツールパネルの垂直スクロール・バーを隠す +PREFERENCES_TUNNELMETADATA;IPTC/XMPの項目は出力するファイルに変更を加えない。 +PREFERENCES_USESYSTEMTHEME;システムのテーマを使う +PREFERENCES_WORKFLOW;レイアウト +PROFILEPANEL_COPYPPASTE;コピーするパラメータ +PROFILEPANEL_FILEDLGFILTERANY;すべてのファイル +PROFILEPANEL_FILEDLGFILTERPP;後処理プロファイル +PROFILEPANEL_LABEL;後処理プロファイル +PROFILEPANEL_LOADDLGLABEL;後処理プロファイルを読み込む... +PROFILEPANEL_LOADPPASTE;読み込むパラメータ +PROFILEPANEL_PASTEPPASTE;貼り付けるパラメータ +PROFILEPANEL_PCUSTOM;カスタム +PROFILEPANEL_PFILE;ファイルから +PROFILEPANEL_PLASTPHOTO;更新済の写真 +PROFILEPANEL_PLASTSAVED;更新済 +PROFILEPANEL_PROFILE;プロファイル +PROFILEPANEL_SAVEDLGLABEL;後処理プロファイルを保存... +PROFILEPANEL_SAVEPPASTE;保存するパラメータ +PROFILEPANEL_TOOLTIPCOPY;クリップボードに現在のプロファイルをコピーします。\nCtrl-クリックでコピーするパラメータを選択します +PROFILEPANEL_TOOLTIPLOAD;ファイルからプロファイルを読み込みます。\nCtrl-クリックで読み込むパラメータを選択します +PROFILEPANEL_TOOLTIPPASTE; クリップボードからプロファイルを貼り付けます。\nCtrl-クリックで貼り付けるパラメータを選択します +PROFILEPANEL_TOOLTIPSAVE;現在のプロファイルを保存。\nCtrl-クリックで保存するパラメータを選択します +PROGRESSBAR_BADPIXELS;不良ピクセル... +PROGRESSBAR_CACORRECTION;色収差補正... +PROGRESSBAR_DARKFRAME;ダークフレーム... +PROGRESSBAR_DECODING;rawファイルデコード中... +PROGRESSBAR_DEMOSAICING;デモザイク処理中... +PROGRESSBAR_GREENEQUIL;グリーン 平衡化... +PROGRESSBAR_LINEDENOISE;ライン ノイズ... +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;ファイル保存中... +QINFO_FOCALLENGTH;焦点距離 +QINFO_ISO;ISO +QINFO_LENS;レンズ +QINFO_NOEXIF;Exifデータがありません +SAVEDLG_AUTOSUFFIX;ファイルが存在する場合、自動的に末尾に文字を加える +SAVEDLG_FILEFORMAT;ファイル形式 +SAVEDLG_JPEGQUAL;JPEG 品質 +SAVEDLG_JPGFILTER;JPEG ファイル +SAVEDLG_PNGCOMPR;PNG 圧縮 +SAVEDLG_PNGFILTER;PNG ファイル +SAVEDLG_PUTTOQUEUEHEAD;キュー処理の最初に追加 +SAVEDLG_PUTTOQUEUETAIL;キュー処理の最後に追加 +SAVEDLG_PUTTOQUEUE;キュー処理に追加 +SAVEDLG_SAVEIMMEDIATELY;すぐに保存 +SAVEDLG_SAVESPP;設定値も保存する +SAVEDLG_TIFFFILTER;TIFF ファイル +SAVEDLG_TIFFUNCOMPRESSED;非圧縮 TIFF +SAVEDLG_WARNFILENAME;ファイルに名前が付けられます +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_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;90度左回転\nショートカット: [ +TP_COARSETRAF_TOOLTIP_ROTRIGHT;90度右回転\nショートカット: ] +TP_COARSETRAF_TOOLTIP_VFLIP;上下反転 +TP_COLORBOOST_ACHANNEL;a チャンネル +TP_COLORBOOST_AMOUNT;適用量 +TP_COLORBOOST_AVOIDCOLORCLIP;カラークリッピング回避 +TP_COLORBOOST_BCHANNEL;b チャンネル +TP_COLORBOOST_CHANNEL;チャンネル +TP_COLORBOOST_CHSEPARATE;a/b分離 +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_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;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_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;(試用) 自動レンズ収差補正 (M4/3, 一部のコンデジ, etc.) +TP_DISTORTION_LABEL;歪曲収差補正 +TP_EPD_EDGESTOPPING;エッジ停止 +TP_EPD_LABEL;トーンマッピング +TP_EPD_REWEIGHTINGITERATES;再重み付けの反復 +TP_EPD_SCALE;スケール +TP_EPD_STRENGTH;強さ +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_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_CURVEEDITOR;トーンカーブ +TP_EXPOSURE_EXPCOMP;露光量補正 +TP_EXPOSURE_LABEL;露光補正 +TP_EXPOSURE_SATURATION;彩度 +TP_EXPO_AFTER; 補間後に(RGB変換前) +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;HSV チャンネル +TP_HSVEQUALIZER_HUE;H +TP_HSVEQUALIZER_LABEL;HSV イコライザ +TP_HSVEQUALIZER_NEUTRAL;ニュートラル +TP_HSVEQUALIZER_SAT;S +TP_HSVEQUALIZER_VAL;V +TP_ICM_BLENDCMSMATRIX;マトリクスとハイライト・ブレンド +TP_ICM_BLENDCMSMATRIX_TOOLTIP;LUTベースのICCプロファイルを使用するときに白トビを修復 +TP_ICM_FILEDLGFILTERANY;すべてのファイル +TP_ICM_FILEDLGFILTERICM;プロファイル ファイル +TP_ICM_INPUTCAMERAICC;カメラの標準 +TP_ICM_INPUTCAMERAICC_TOOLTIP;RawTherapeeのデフォルトの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_OUTPUTDLGLABEL;出力 ICC プロファイルを選択... +TP_ICM_OUTPUTPROFILE;出力プロファイル +TP_ICM_PREFERREDPROFILE;DCPプロファイル優先 +TP_ICM_PREFERREDPROFILE_1;昼光 +TP_ICM_PREFERREDPROFILE_2;タングステン +TP_ICM_PREFERREDPROFILE_3;蛍光灯 +TP_ICM_PREFERREDPROFILE_4;フラッシュ +TP_ICM_SAVEREFERENCE;プロファイリングの参照する画像を保存 +TP_ICM_WORKINGPROFILE;作業プロファイル +TP_IMPULSEDENOISE_LABEL;インパルス ノイズ低減 +TP_IMPULSEDENOISE_THRESH;インパルス NR しきい値 +TP_LABCURVE_AVOIDCOLORCLIP;カラークリッピング回避 +TP_LABCURVE_BRIGHTNESS;明るさ +TP_LABCURVE_BWTONING;白黒トーン +TP_LABCURVE_BWTONING_TIP;白黒トーン オプションを有効にすると、Lab調整の彩度は無効になります。\n色調は ab カーブで調整することができます。 +TP_LABCURVE_CONTRAST;コントラスト +TP_LABCURVE_CURVEEDITOR;Lab 明度カーブ +TP_LABCURVE_ENABLESATLIMITER;彩度制限・有効 +TP_LABCURVE_LABEL;Lab 調整 +TP_LABCURVE_SATLIMIT;彩度の制限 +TP_LABCURVE_SATURATION;彩度 +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_LUMADENOISE_EDGETOLERANCE;エッジの許容度 +TP_LUMADENOISE_LABEL;輝度 ノイズ低減 +TP_LUMADENOISE_RADIUS;半径 +TP_NEUTRAL;ニュートラル +TP_NEUTRAL_TIP;露光量の制御をニュートラルな値にリセットします +TP_PERSPECTIVE_HORIZONTAL;水平 +TP_PERSPECTIVE_LABEL;パースペクティブ +TP_PERSPECTIVE_VERTICAL;垂直 +TP_PREPROCESS_DARKFRAME;ダークフレーム +TP_PREPROCESS_DFAUTOSELECT;自動選択 +TP_PREPROCESS_FLATFIELDAUTOSELECT;フラットフィールド自動選択 +TP_PREPROCESS_FLATFIELDBLURRADIUS;フラットフィールド・ぼかし半径 +TP_PREPROCESS_FLATFIELDBLURTYPE;フラットフィールド・ぼかしタイプ +TP_PREPROCESS_FLATFIELDFILE;フラットフィールド +TP_PREPROCESS_GREENEQUIL;グリーン 平衡化 +TP_PREPROCESS_HOTDEADPIXFILT;ホット/デッド ピクセル・フィルタを適用 +TP_PREPROCESS_HOTDEADPIXTHRESH;ホット/デッド・ピクセル検出のしきい値 +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;2つのグリーンを共に +TP_RAWPANEL_DEMOSAICING;デモザイク +TP_RAWPANEL_PREPROCESSING;前処理 +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_FULLSIZE;フル 画像 サイズ: +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_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_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_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;タングステン +ZOOMBAR_DETAIL;ディテール +ZOOMBAR_HUGE;特大 +ZOOMBAR_LARGE;大 +ZOOMBAR_NORMAL;標準 +ZOOMBAR_PREVIEW;表示 +ZOOMBAR_SCALE;スケール +ZOOMBAR_SMALL;小 +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;新規ディテール ウィンドウを開く +ZOOMPANEL_ZOOM100;100%にズーム\nショートカット: 1 +ZOOMPANEL_ZOOMFITSCREEN;画面に合わせる\nショートカット: f +ZOOMPANEL_ZOOMIN;ズームイン\nショートカット: + +ZOOMPANEL_ZOOMOUT;ズームアウト\nショートカット: - + +#00 Japanese +#01 Translated by a3novy +#02 update: 2011-05-15 +#03 update: 2011-11-13, update: 2011-11-20 (for 4.0.5) +#04 update: 2011-12-03 (for 4.0.6) +#05 update: 2012-02-11 (for 4.0.7) +#06 update: 2012-04-04 (for 4.0.8) +#07 update: 2012-07-12 (for 4.0.9) + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!HISTOGRAM_TOOLTIP_FULL;Toggle full or scaled histogram +!HISTORY_MSG_168;'Cc' curve +!HISTORY_MSG_169;'Ch' curve +!HISTORY_MSG_170;Vibrance - Curve +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing Profile Saved +!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 +!SHCSELECTOR_TOOLTIP;Click right mouse button to reset\nthe position of those 3 sliders +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid Color Shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space\nand apply Munsell correction +!TP_LABCURVE_CHROMATICITY;Chromaticity +!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 the Chromaticity +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to the Hue +!TP_LABCURVE_RSTPROTECTION;Red and Skin Tones Protection +!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 the Hue diff --git a/rtdata/languages/LICENSE b/rtdata/languages/LICENSE new file mode 100644 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..17d5ac465 --- /dev/null +++ b/rtdata/languages/Latvian @@ -0,0 +1,1207 @@ +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_DIALOGLABEL;Exif Filtrs +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_ARRANGEMENTHINT;Pārslēgt sīktēlu izvietojumu vertikāli/horizontāli +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_EXIFFILTERAPPLYHINT;Pārslēgt failu pārlūka exif filtru +FILEBROWSER_EXIFFILTERAPPLY;Lietot +FILEBROWSER_EXIFFILTERLABEL;Exif filtrs +FILEBROWSER_EXIFFILTERSETTINGSHINT;Mainīt exif filtra uzstādījumus +FILEBROWSER_EXIFFILTERSETTINGS;Uzstādījumi +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_POPUPRANK1;Vērtēt 1 +FILEBROWSER_POPUPRANK2;Vērtēt 2 +FILEBROWSER_POPUPRANK3;Vērtēt 3 +FILEBROWSER_POPUPRANK4;Vērtēt 4 +FILEBROWSER_POPUPRANK5;Vērtēt 5 +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_PROCESSINGSETTINGSHINT;Uzstādīt failu formātu un izvades direktoriju +FILEBROWSER_PROCESSINGSETTINGS;Uzstādījumi +FILEBROWSER_RENAMEDLGLABEL;Pārsaukt failu +FILEBROWSER_RENAMEDLGMSG;Pārsaukt failu "%1" uz: +FILEBROWSER_SHOWDIRHINT;Rādīt visus direktorija attēlus +FILEBROWSER_SHOWQUEUEHINT;Rādīt apstrādes rindu +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_LOAD;Ielādēt +GENERAL_NA;n/a +GENERAL_NO;Nē +GENERAL_OK;Labi +GENERAL_PORTRAIT;Portrets +GENERAL_SAVE;Saglabāt +GENERAL_YES;Jā +HISTOGRAM_LABEL;Histogramma +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_NEWSNAPSHOTAS;Kā... +HISTORY_NEWSNAPSHOT;Jauna grāmtzīme +HISTORY_NEWSSDIALOGLABEL;Grāmtzīmes nosaukums: +HISTORY_NEWSSDIALOGTITLE;Pielikt grāmtzīmi +HISTORY_SETTO;Iestatīts uz +HISTORY_SNAPSHOTS;Grāmtzīmes +HISTORY_SNAPSHOT;Grāmtzīme +ICMPANEL_FILEDLGFILTERANY;Visi faili +ICMPANEL_FILEDLGFILTERICM;ICC Profilu faili +ICMPANEL_GAMMABEFOREINPUT;Uzlikta Gammu pirms Ievades profila +ICMPANEL_INPUTCAMERA;Kameras noklusētais +ICMPANEL_INPUTCUSTOM;Pielāgots +ICMPANEL_INPUTDLGLABEL;Izvēlies Ievades ICC Profilu... +ICMPANEL_INPUTEMBEDDED;Lietot iegulto, ja var +ICMPANEL_INPUTPROFILE;Ievades profils +ICMPANEL_NOICM;Bez ICM: sRGB izvade +ICMPANEL_OUTPUTDLGLABEL;Izvēlies Izvades ICC Profilu... +ICMPANEL_OUTPUTPROFILE;Izvades profils +ICMPANEL_SAVEREFERENCE;Saglabāt atsauces attēlu profila izveidei +ICMPANEL_WORKINGPROFILE;Darba profils +IMAGEAREA_DETAILVIEW;Tuvskats +IPTCPANEL_AUTHORHINT;Objekta radītājs vārds, t.i. rakstnieks, fotogrāfs vai mākslinieks (By-line). +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_EXIT;Exit +MAIN_BUTTON_PREFERENCES;Iestatījumi +MAIN_BUTTON_QUEUE;Put to queue +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_EXITJOBSINQUEUEINFO;Beidzot neapstrādātie attēli no rindas pazudīs. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Vai tiešām beigt? Apstrādes rindā ir neapstrādāti attēli. +MAIN_MSG_JOBSINQUEUE;darbs(i) rindā +MAIN_MSG_QOVERWRITE;Vai pārrakstīt to? +MAIN_TAB_BASIC;Pamats +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_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadati +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;Pārveidot +MAIN_TOOLTIP_HIDEFP;Rādīt/slēpt apakšējo ielaidumu (mapju un failu pārlūks, saīsne: F)) +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_PREFERENCES;Mainīt iestatījumus +MAIN_TOOLTIP_QINFO;Ātrā info uz attēla +MAIN_TOOLTIP_SAVEAS;Saglabāt attēlu izvēlētajā mapē +MAIN_TOOLTIP_SAVE;Saglabāt attēlu noklusētajā mapē +PARTIALPASTE_BASICGROUP;Pamata uzstādījumi +PARTIALPASTE_CACORRECTION;Krāsu novirzes labošana +PARTIALPASTE_COARSETRANS;90 grādu rotēšana / apmešana +PARTIALPASTE_COLORBOOST;Krāsu pastiprināšana +PARTIALPASTE_COLORDENOISE;Krāsu attīrīšana +PARTIALPASTE_COLORGROUP;Krāsu uzstādījumi +PARTIALPASTE_COLORMIXER;Krāsu jaucējs +PARTIALPASTE_COLORSHIFT;Krāsu nobīde +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_HLRECOVERY;Izgaismojumu atgūšana +PARTIALPASTE_ICMSETTINGS;ICM uzstādījumi +PARTIALPASTE_IPTCINFO;IPTC info +PARTIALPASTE_LENSGROUP;Lēcas uzstādījumi +PARTIALPASTE_LUMACURVE;Spīduma līkne +PARTIALPASTE_LUMADENOISE;Spīduma trokšņu slāpēšana +PARTIALPASTE_LUMINANCEGROUP;Spīduma uzstādījumi +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_CACHESTRAT1;Priekšroka ātrumam pret mazu atmiņas patēriņu +PREFERENCES_CACHESTRAT2;Priekšroka mazam atmiņas patēriņam pret ātrumu +PREFERENCES_CACHESTRAT;Keša stratēģija +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_DEMOSAICINGALGO;Mozaīkas interpolācijas algoritms +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_HINT;Mājiens +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_LIVETHUMBNAILS;Dzīvie sīktēli (lēnāk) +PREFERENCES_MONITORICC;Monitora Profils +PREFERENCES_OUTDIRFOLDERHINT;Likt saglabātos attēlus norādītajā mapē +PREFERENCES_OUTDIRFOLDER;Saglabāt mapē +PREFERENCES_OUTDIRHINT;Jūs varat lietot šāduas formatēšanas parametrus:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nŠie formatēšanas parametri attiecas uz raw faila direktoriju un apakšceļiem.\n\nPiemēram, ja /home/tom/image/02-09-2006/dsc0012.nef ir atvērts, formatēšanas parametri nozīmē:\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 Jūs vēlaties saglabāt rezultātu tur pat kur ir oriģināls, rakstiet:\n%p1/%f\n\nJa Jūs vēlaties saglabāt rezultātu direktorijā 'converted', kas novietota oriģināla direktorijā, rakstiet:\n%p1/converted/%f\n\nJa Jūs vēlaties saglabāt rezultātu '/home/tom/converted' paturot tādu pašu apakšdirektoriju datumu struktūru, rakstiet:\n%p2/converted/%d1/%f +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_SELECTICCDIRDLG;Izvēlies ICC Profilu mapi... +PREFERENCES_SELECTLANG;Izvēlies valodu +PREFERENCES_SELECTMONITORPROFDLG;Izvēlies displeja ICC profilu... +PREFERENCES_SELECTTHEME;Izvēlieties tēmu +PREFERENCES_SHOWBASICEXIF;Rādīt Exif pamatdatus +PREFERENCES_SHOWDATETIME;Rādīt datumu un laiku +PREFERENCES_SHOWONLYRAW;Rādīt tikai RAW failus +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 +PREFERENCES_TAB_OUTPUT;Izvades iespējas +PREFERENCES_THUMBSIZE;Sīktēla izmērs +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_PLASTPHOTO;Iepriekšējais attēls +PROFILEPANEL_PLASTSAVED;Pēdējais saglabātais +PROFILEPANEL_PROFILE;Profils +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_DECODING;Dekodēju raw failu... +PROGRESSBAR_DEMOSAICING;Mozaīkas interpolācija... +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_FOCALLENGTH;Fokusa garums +QINFO_ISO;ISO +QINFO_LENS;Lēca +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_PNGFILTER;PNG faili +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_OUTPUTDLGLABEL;Izvēlies Izvades ICC Profilu... +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_LUMADENOISE_EDGETOLERANCE;Iecietība pret malām +TP_LUMADENOISE_LABEL;Spīduma trokšņu slāpēšana +TP_LUMADENOISE_RADIUS;Radiuss +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_FULLSIZE;Pilns attēla izmērs: +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 +ZOOMBAR_DETAIL;Tuvskats +ZOOMBAR_HUGE;Milzīgs +ZOOMBAR_LARGE;Liels +ZOOMBAR_NORMAL;Normāls +ZOOMBAR_PREVIEW;Pirmsskats +ZOOMBAR_SCALE;Mērogs +ZOOMBAR_SMALL;Mazs + +#00 Latvian +# + +!!!!!!!!!!!!!!!!!!!!!!!!! +! 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 +!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_SHARPENEDGE;Bypass Edge Sharpening +!EXPORT_BYPASS_SHARPENING;Bypass Sharpening +!EXPORT_BYPASS_SHARPENMICRO;Bypass Microcontrast +!EXPORT_BYPASS_SH_HQ;Bypass Shadow/Highlights (High Quality) +!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 the path text box.\nEnter / Ctrl-Enter (in the File Browser) to browse there;\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_CURRENT_NAME;Current name: +!FILEBROWSER_DARKFRAME;Dark frame +!FILEBROWSER_DELETEDLGMSGINCLPROC;Are you sure you want to delete the selected %1 files including a queue-processed version? +!FILEBROWSER_EXEC_CPB;Custom Profile Builder +!FILEBROWSER_EXTPROGMENU;Open with +!FILEBROWSER_FLATFIELD;Flat Field +!FILEBROWSER_MOVETODARKFDIR;Move to dark frames directory +!FILEBROWSER_MOVETOFLATFIELDDIR;Move to flat fields directory +!FILEBROWSER_NEW_NAME;New name: +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!FILEBROWSER_POPUPCOLORLABEL0;Label: None +!FILEBROWSER_POPUPCOLORLABEL1;Label: Red +!FILEBROWSER_POPUPCOLORLABEL2;Label: Yellow +!FILEBROWSER_POPUPCOLORLABEL3;Label: Green +!FILEBROWSER_POPUPCOLORLABEL4;Label: Blue +!FILEBROWSER_POPUPCOLORLABEL5;Label: Purple +!FILEBROWSER_POPUPCOLORLABEL;Color label +!FILEBROWSER_POPUPCOPYTO;Copy to... +!FILEBROWSER_POPUPFILEOPERATIONS;File Operations +!FILEBROWSER_POPUPMOVETO;Move to... +!FILEBROWSER_POPUPPROCESSFAST;Put to Queue (Fast export) +!FILEBROWSER_POPUPPROFILEOPERATIONS;Processing Profile Operations +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_POPUPREMOVESUBMENU;Remove +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!FILEBROWSER_QUERYHINT;Type a partial filename to search for.\nCtrl-F to focus the Find text box (in the File Browser).\nEnter to commence search. +!FILEBROWSER_QUERYLABEL; Find: +!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 +!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-` +!FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +!FILEBROWSER_USETEMPLATE;Use template: +!GENERAL_AFTER;After +!GENERAL_BEFORE;Before +!GENERAL_FILE;File +!GENERAL_HIGH_QUALITY;High Quality +!GENERAL_NONE;None +!GENERAL_UNCHANGED;(Unchanged) +!GENERAL_WARNING;Warning +!HISTOGRAM_BUTTON_BAR;RGB +!HISTOGRAM_BUTTON_B;B +!HISTOGRAM_BUTTON_G;G +!HISTOGRAM_BUTTON_L;L +!HISTOGRAM_BUTTON_RAW;Raw +!HISTOGRAM_BUTTON_R;R +!HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar\nClick right mouse button on image preview to freeze/unfreeze +!HISTOGRAM_TOOLTIP_FULL;Toggle full or scaled histogram +!HISTOGRAM_TOOLTIP_RAW;Show/Hide raw histogram +!HISTORY_MSG_82;Profile Changed +!HISTORY_MSG_83;High Quality Shadows/Highlights +!HISTORY_MSG_84;Perspective Correction +!HISTORY_MSG_85;Lens Correction Profile +!HISTORY_MSG_86;Wavelet Equalizer +!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 +!HISTORY_MSG_92;NR - Gamma +!HISTORY_MSG_93;Contrast by Detail Levels Value +!HISTORY_MSG_94;Contrast by Detail Levels +!HISTORY_MSG_95;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;RGB Saturation +!HISTORY_MSG_101;HSV EQ -- Hue +!HISTORY_MSG_102;HSV EQ -- Saturation +!HISTORY_MSG_103;HSV EQ -- Value +!HISTORY_MSG_104;HSV Equalizer +!HISTORY_MSG_105;Defringing +!HISTORY_MSG_106;Defringing Radius +!HISTORY_MSG_107;Defringing Threshold +!HISTORY_MSG_108;Highlight Compr. Threshold +!HISTORY_MSG_109;Resize Bounding Box +!HISTORY_MSG_110;Resizing applies o +!HISTORY_MSG_111;Avoid Color Shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;Red and Skin Tones Protection +!HISTORY_MSG_114;DCB Iterations +!HISTORY_MSG_115;False Color Iterations +!HISTORY_MSG_116;Enhanced DCB +!HISTORY_MSG_117;Red CA Correction +!HISTORY_MSG_118;Blue CA Correction +!HISTORY_MSG_119;Line Denoise +!HISTORY_MSG_120;Green Equil. Threshold +!HISTORY_MSG_121;Auto CA +!HISTORY_MSG_122;Auto Dark Frame +!HISTORY_MSG_123;Dark Frame File +!HISTORY_MSG_124;Linear Exp. Correction +!HISTORY_MSG_125;Exp. Correction Preserving HL +!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;Gamma +!HISTORY_MSG_134;Gamma Position +!HISTORY_MSG_135;Gamma Free +!HISTORY_MSG_136;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 Green Together +!HISTORY_MSG_142;Edges Sharpening - Iterations +!HISTORY_MSG_143;Edges Sharpening - Quantity +!HISTORY_MSG_144;Microcontrast - Quantity +!HISTORY_MSG_145;Microcontrast - Uniformity +!HISTORY_MSG_146;Edges Sharpening +!HISTORY_MSG_147;Edges Sharpening - 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;Vibrance - Pastel tones +!HISTORY_MSG_153;Vibrance - Saturated tones +!HISTORY_MSG_154;Vibrance - Protect skin tones +!HISTORY_MSG_155;Vibrance - Avoid color drift +!HISTORY_MSG_156;Vibrance - Link pastel and saturated tones +!HISTORY_MSG_157;Vibrance - Pastel/Saturated threshold +!HISTORY_MSG_158;Strength +!HISTORY_MSG_159;Edge Stopping +!HISTORY_MSG_160;Scale +!HISTORY_MSG_161;Reweighting Iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_163;RGB Curves - R +!HISTORY_MSG_164;RGB Curves - G +!HISTORY_MSG_165;RGB Curves - B +!HISTORY_MSG_166;Neutral Levels +!HISTORY_MSG_167;B&W Toning +!HISTORY_MSG_168;'Cc' curve +!HISTORY_MSG_169;'Ch' curve +!HISTORY_MSG_170;Vibrance - Curve +!MAIN_BUTTON_FULLSCREEN;Fullscreen +!MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Put current image to processing queue.\nShortcut: Ctrl+Q +!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_ERRORDURINGIMAGESAVING;Error during image saving +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue processed first. +!MAIN_MSG_NAVIGATOR;Navigator +!MAIN_MSG_PLACES;Places +!MAIN_TAB_COLOR_TOOLTIP;Shortcut: Alt-C +!MAIN_TAB_DETAIL_TOOLTIP;Shortcut: Alt-D +!MAIN_TAB_EXPORT; 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_TOGGLE_BEFORE_AFTER;B|A +!MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 8 +!MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 0 +!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_CHANNELMIXER;Channel mixer +!PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto fill +!PARTIALPASTE_DARKFRAMEAUTOSELECT;Dark Frame Auto Select +!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;FF Auto Select +!PARTIALPASTE_FLATFIELDBLURRADIUS;FF Blur Radius +!PARTIALPASTE_FLATFIELDBLURTYPE;FF Blur Type +!PARTIALPASTE_FLATFIELDFILE;Flat field (FF) File +!PARTIALPASTE_HLRECONSTRUCTION;Highlight reconstruction +!PARTIALPASTE_HLRECOVERYAMOUNT;Highlight recovery amount +!PARTIALPASTE_HLRECOVERYTHRESHOLD;Highlight recovery threshold +!PARTIALPASTE_HSVEQUALIZER;HSV Equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!PARTIALPASTE_LABCURVE;Lab adjustments +!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 Level +!PARTIALPASTE_RAWEXPOS_LINEAR;Raw white point linear corr. factor +!PARTIALPASTE_RAWEXPOS_PRESER;Raw white point HL preserving corr. (EV) +!PARTIALPASTE_RAWGROUP;Raw settings +!PARTIALPASTE_RAW_ALLENHANCE;Apply post demosaic artifact/noise reduction +!PARTIALPASTE_RAW_DCBENHANCE;Apply DCB enhancement step +!PARTIALPASTE_RAW_DCBITERATIONS;Number of DCB iterations +!PARTIALPASTE_RAW_DMETHOD;Demosaic Method +!PARTIALPASTE_RAW_FALSECOLOR;Demosaic False color suppression steps +!PARTIALPASTE_RGBCURVES;RGB curves +!PARTIALPASTE_SHARPENEDGE;Edges +!PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_VIBRANCE;Vibrance +!PARTIALPASTE_WAVELETEQUALIZER;Wavelet equalizer +!PREFERENCES_ADD;ADD +!PREFERENCES_AUTOMONPROFILE;Automatically use operating system's main monitor color profile +!PREFERENCES_BATCH_PROCESSING;Batch Processing +!PREFERENCES_BEHAVIOR;Behavior +!PREFERENCES_CUSTPROFBUILDHINT;Executable (or script) file called when a new initial processing profile should be generated for an image.\nReceives command line parameters to allow a rules-based processing profile generation:\n[raw/JPG path] [default processing profile path] [f-number] [exposure in secs] [focal length in mm] [ISO] [lens] [camera] +!PREFERENCES_CUSTPROFBUILDPATH;Executable path +!PREFERENCES_CUSTPROFBUILD;Custom Processing Profile Builder +!PREFERENCES_CUTOVERLAYBRUSH;Crop mask color/transparency +!PREFERENCES_DARKFRAMEFOUND;Found +!PREFERENCES_DARKFRAMESHOTS;shots +!PREFERENCES_DARKFRAMETEMPLATES;templates +!PREFERENCES_DARKFRAME;Dark Frame +!PREFERENCES_DATEFORMATFRAME;Date Format +!PREFERENCES_DIRDARKFRAMES;Dark frames directory +!PREFERENCES_EDITORLAYOUT;Editor Layout +!PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar (de-select for low res display) +!PREFERENCES_FLATFIELDFOUND;Found +!PREFERENCES_FLATFIELDSDIR;Flat Fields directory +!PREFERENCES_FLATFIELDSHOTS;shots +!PREFERENCES_FLATFIELDTEMPLATES;templates +!PREFERENCES_FLATFIELD;Flat Field +!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_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). On Windows use "SystemDefault", "SystemAsterisk" etc. for system sounds. +!PREFERENCES_SND_LNGEDITPROCDONE;Editor processing done +!PREFERENCES_SND_TRESHOLDSECS;after secs +!PREFERENCES_SQUAREDETAILWINDOW;Square detail window (faster) +!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_USESYSTEMTHEME; Use system theme +!PREFERENCES_WORKFLOW;Layout +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_SAVEPPASTE;Parameters to save +!PROGRESSBAR_BADPIXELS;Bad pixels... +!PROGRESSBAR_CACORRECTION;CA correction... +!PROGRESSBAR_DARKFRAME;Darkframe... +!PROGRESSBAR_GREENEQUIL;Green equilibrate... +!PROGRESSBAR_LINEDENOISE;Line Denoise... +!PROGRESSBAR_LOADINGTHUMBS;Loading thumbnails... +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing Profile Saved +!PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists +!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\nthe 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_CHROMATABERR_LABEL;Chromatic Aberration +!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_DETAIL_AMOUNT;Amount +!TP_DIRPYRDENOISE_CHROMA;Chrominance +!TP_DIRPYRDENOISE_GAMMA;Gamma +!TP_DIRPYRDENOISE_LABEL;Noise reduction +!TP_DIRPYRDENOISE_LUMA;Luminance +!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_EQUALIZER_CONTRAST_MINUS;Contrast- +!TP_EQUALIZER_CONTRAST_PLUS;Contrast+ +!TP_EQUALIZER_FINEST;finest +!TP_EQUALIZER_LABEL;Wavelet equalizer +!TP_EQUALIZER_LARGEST;coarsest +!TP_EQUALIZER_NEUTRAL;Neutral +!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 +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in auto levels operation +!TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Highlight recovery threshold +!TP_EXPOSURE_SATURATION;Saturation +!TP_EXPO_AFTER; After interpolation (before RGB conversion) +!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_HLREC_BLEND;Blend +!TP_HSVEQUALIZER_CHANNEL;HSV Channel +!TP_HSVEQUALIZER_HUE;H +!TP_HSVEQUALIZER_LABEL;HSV Equalizer +!TP_HSVEQUALIZER_NEUTRAL;Neutral +!TP_HSVEQUALIZER_SAT;S +!TP_HSVEQUALIZER_VAL;V +!TP_ICM_BLENDCMSMATRIX;Blend highlights with matrix +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover blown highlights when using LUT based ICC profiles +!TP_ICM_INPUTCAMERAICC;Auto-matched camera-specific color profile +!TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profile. These profiles are more precise than simpler matrix ones. Available for some 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_PREFERREDPROFILE;Preferred DCP profile +!TP_ICM_PREFERREDPROFILE_1;Daylight +!TP_ICM_PREFERREDPROFILE_2;Tungsten +!TP_ICM_PREFERREDPROFILE_3;Fluorescent +!TP_ICM_PREFERREDPROFILE_4;Flash +!TP_IMPULSEDENOISE_LABEL;Impulse Noise Reduction +!TP_IMPULSEDENOISE_THRESH;Impulse NR Threshold +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid Color Shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space\nand apply Munsell correction +!TP_LABCURVE_BRIGHTNESS;Brightness +!TP_LABCURVE_BWTONING;B&W Toning +!TP_LABCURVE_BWTONING_TIP;With B&W Toning option enabled, the Lab Chromaticity, Cc and Ch curves are not in effect.\nToning can be achieved using the a and b curves +!TP_LABCURVE_CHROMATICITY;Chromaticity +!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 the Chromaticity +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to the Hue +!TP_LABCURVE_LABEL;Lab Adjustments +!TP_LABCURVE_RSTPROTECTION;Red and Skin Tones Protection +!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;Use CA correction +!TP_LENSPROFILE_USEDIST;Use distortion correction +!TP_LENSPROFILE_USEVIGN;Use vignette correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset exposure controls to neutral values +!TP_PERSPECTIVE_HORIZONTAL;Horizontal +!TP_PERSPECTIVE_LABEL;Perspective +!TP_PERSPECTIVE_VERTICAL;Vertical +!TP_PREPROCESS_GREENEQUIL;Green equilibration +!TP_PREPROCESS_HOTDEADPIXFILT;Apply hot/dead pixel filter +!TP_PREPROCESS_HOTDEADPIXTHRESH;Hot/dead pixel detection threshold +!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 (leader) +!TP_RAWEXPOS_LINEAR;White Point: Linear corr. factor +!TP_RAWEXPOS_PRESER;White Point: HL preserving corr.(EV) +!TP_RAWEXPOS_TWOGREEN;Two greens together +!TP_RAW_ALLENHANCE;Apply post demosaic artifact/noise reduction +!TP_RAW_DCBENHANCE;Apply DCB enhancement step +!TP_RAW_DCBITERATIONS;Number of DCB iterations +!TP_RAW_LABEL;Demosaicing +!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_RED;R +!TP_SHARPENEDGE_AMOUNT;Quantity +!TP_SHARPENEDGE_LABEL;Edges +!TP_SHARPENEDGE_PASSES;Iterations +!TP_SHARPENEDGE_THREE;Luminance only +!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 the Hue +!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_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 +!ZOOMPANEL_100;(100%) +!ZOOMPANEL_NEWCROPWINDOW;Open (new) detail window +!ZOOMPANEL_ZOOM100;Zoom to 100% 1 +!ZOOMPANEL_ZOOMFITSCREEN;Fit to screen F +!ZOOMPANEL_ZOOMIN;Zoom In + +!ZOOMPANEL_ZOOMOUT;Zoom Out - diff --git a/rtdata/languages/Magyar b/rtdata/languages/Magyar new file mode 100644 index 000000000..68d3c11f8 --- /dev/null +++ b/rtdata/languages/Magyar @@ -0,0 +1,1223 @@ +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_DIALOGLABEL;EXIF szűrő +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_ARRANGEMENTHINT;Váltás az előnézeti képek függőleges/vízszintes elrendezése között +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_EXIFFILTERAPPLYHINT;Az EXIF szűrő ki-/bekapcsolása +FILEBROWSER_EXIFFILTERAPPLY;Aktív +FILEBROWSER_EXIFFILTERLABEL;EXIF szűrő +FILEBROWSER_EXIFFILTERSETTINGSHINT;Az EXIF szűrő beállítása +FILEBROWSER_EXIFFILTERSETTINGS;Beállítások +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_POPUPCOLORLABEL0;Címke: Nincs +FILEBROWSER_POPUPCOLORLABEL1;Címke: Piros +FILEBROWSER_POPUPCOLORLABEL2;Címke: Sárga +FILEBROWSER_POPUPCOLORLABEL3;Címke: Zöld +FILEBROWSER_POPUPCOLORLABEL4;Címke: Kék +FILEBROWSER_POPUPCOLORLABEL5;Címke: Lila +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_POPUPRANK1;Jelölés 1 csillaggal +FILEBROWSER_POPUPRANK2;Jelölés 2 csillaggal +FILEBROWSER_POPUPRANK3;Jelölés 3 csillaggal +FILEBROWSER_POPUPRANK4;Jelölés 4 csillaggal +FILEBROWSER_POPUPRANK5;Jelölés 5 csillaggal +FILEBROWSER_POPUPREMOVEINCLPROC;Törlés (feldolgozási sorból is) +FILEBROWSER_POPUPREMOVESUBMENU;Eltávolítás +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_PROCESSINGSETTINGSHINT;A fájl formátum és a célkönyvtár beállítása +FILEBROWSER_PROCESSINGSETTINGS;Beállítások +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_SHOWQUEUEHINT;A feldolgozási sor tartalmának mutatása +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-` +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_HIGH_QUALITY;Jó minőségben +GENERAL_LANDSCAPE;Fekvő +GENERAL_LOAD;Betöltés +GENERAL_NA;n/a +GENERAL_NONE;Nincs +GENERAL_NO;Nem +GENERAL_OK;OK +GENERAL_PORTRAIT;Álló +GENERAL_SAVE;Mentés +GENERAL_UNCHANGED;(Változatlan) +GENERAL_YES;Igen +HISTOGRAM_BUTTON_BAR;RGB +HISTOGRAM_BUTTON_B;B +HISTOGRAM_BUTTON_G;G +HISTOGRAM_BUTTON_L;L +HISTOGRAM_BUTTON_RAW;Raw +HISTOGRAM_BUTTON_R;R +HISTOGRAM_LABEL;Hisztogram +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_NEWSNAPSHOTAS;címkével... +HISTORY_NEWSNAPSHOT;Új +HISTORY_NEWSSDIALOGLABEL;Pillanatkép cimkéje: +HISTORY_NEWSSDIALOGTITLE;Új pillanatkép +HISTORY_SETTO;új érték: +HISTORY_SNAPSHOTS;Pillanatképek +HISTORY_SNAPSHOT;Pillanatkép +ICMPANEL_FILEDLGFILTERANY;Minden fájl +ICMPANEL_FILEDLGFILTERICM;ICC színprofil fájl +ICMPANEL_GAMMABEFOREINPUT;Gamma korrekció a bemeneti profil előtt +ICMPANEL_INPUTCAMERA;Fényképezőgép szerinti alapértelmezett +ICMPANEL_INPUTCUSTOM;Saját +ICMPANEL_INPUTDLGLABEL;Bemeneti színprofil kiválasztása... +ICMPANEL_INPUTEMBEDDED;Beágyazott profil, ha van +ICMPANEL_INPUTPROFILE;Bemeneti színprofil +ICMPANEL_NOICM;Nincs színkezelés: sRGB kimenet +ICMPANEL_OUTPUTDLGLABEL;Kimeneti színprofil kiválasztása... +ICMPANEL_OUTPUTPROFILE;Kimeneti színprofil +ICMPANEL_SAVEREFERENCE;Referencia kép mentése profil kalibráláshoz +ICMPANEL_WORKINGPROFILE;Munka színprofil +IMAGEAREA_DETAILVIEW;Részlet nézet +IPTCPANEL_AUTHORHINT;A kép létrehozójának neve, pl. író, fényképész, grafikus művész (By-line) +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_EXIT;Kilépés +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+Q +MAIN_BUTTON_QUEUE;Feldolgozási sorba helyezés +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_ERRORDURINGIMAGESAVING;Hiba történt a kép mentése során! +MAIN_MSG_EXITJOBSINQUEUEINFO;A sorban álló feldolgozatlan képek kilépéskor el fognak veszni. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Biztos, hogy ki akar lépni? Feldolgozatlan képek vannak a feldolgozási sorban. +MAIN_MSG_JOBSINQUEUE;tennivaló vár a sorban +MAIN_MSG_NAVIGATOR;Navigátor +MAIN_MSG_PLACES;Helyek +MAIN_MSG_QOVERWRITE;Felülírjam? +MAIN_TAB_BASIC;Alap +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_ICM;ICM +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_TOGGLE_BEFORE_AFTER;E|U +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_HIDEFP;A fájlkezelő alsó panel elrejtése/megjelenítése (Gyorsbillentyű: F) +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_PREFERENCES;Beállítások megváltoztatása +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_SAVEAS;A kép mentése a kiválasztott könyvtárba +MAIN_TOOLTIP_SAVE;A kép mentése az alapértelmezett könyvtárba az alapértelmezett néven +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_COLORBOOST;Színtelítettség +PARTIALPASTE_COLORDENOISE;Színzaj-csökkentés +PARTIALPASTE_COLORGROUP;Színeket érintő beállítások +PARTIALPASTE_COLORMIXER;Színkeverő +PARTIALPASTE_COLORSHIFT;Színeltolás +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_HLRECONSTRUCTION;Csúcsfény-helyreállítá +PARTIALPASTE_HLRECOVERYAMOUNT;Csúcsfény-helyreállítás mértéke +PARTIALPASTE_HLRECOVERYTHRESHOLD;Csúcsfény-helyreállítás küszöbe +PARTIALPASTE_HLRECOVERY;Kiégett részletek megmentése +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_LUMADENOISE;Luminanciazaj-csökkentés +PARTIALPASTE_LUMINANCEGROUP;Luminanciát érintő beállítások +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_WAVELETEQUALIZER;Wavelet equalizer +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_CACHESTRAT1;Inkább gyors, mint memóriatakarékos +PREFERENCES_CACHESTRAT2;Inkább memóriatakarékos, mint gyors +PREFERENCES_CACHESTRAT;Gyorsítótár stratégia +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_DEMOSAICINGALGO;Bayer interpoláció +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_HINT;Tipp +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_LIVETHUMBNAILS;Élő előnézeti képek (lassabb) +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_OUTDIRHINT;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 szeretnéd 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 szeretnéd 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 szeretnéd menteni az eredeti, dátumot tartalmazó alkönyvtár megtartásával, írd ezt:\n%p2/converted/%d1/%f +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_SELECTICCDIRDLG;ICC profilok könyvtárának kiválasztása... +PREFERENCES_SELECTLANG;Nyelv kiválasztása +PREFERENCES_SELECTMONITORPROFDLG;Monitor ICC profiljának 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_SHOWONLYRAW;Csak a RAW fájok 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_OUTPUT;Állománymentési beállítások +PREFERENCES_TAB_SOUND;Hangok +PREFERENCES_THUMBSIZE;Képek mérete a böngészőben +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_PLASTPHOTO;Előző fotó +PROFILEPANEL_PLASTSAVED;Legutóbb használt +PROFILEPANEL_PROFILE;Beállítások +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_BADPIXELS;Hibás pixelek... +PROGRESSBAR_CACORRECTION;Színihiba-javítás (CA korrekció +PROGRESSBAR_DARKFRAME;Fekete referenciakép (dark frame)... +PROGRESSBAR_DECODING;Raw állomány dekódolása... +PROGRESSBAR_DEMOSAICING;Bayer interpoláció... +PROGRESSBAR_GREENEQUIL;Zöldegyensúly... +PROGRESSBAR_LINEDENOISE;Soronkénti zajszűrés... +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_FOCALLENGTH;Fokális távolság +QINFO_ISO;ISO +QINFO_LENS;Objektív +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_PNGFILTER;PNG fájlok +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_NEUTRAL;Semleges +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_OUTPUTDLGLABEL;Kimeneti színprofil kiválasztása... +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_LUMADENOISE_EDGETOLERANCE;Éltolerancia +TP_LUMADENOISE_LABEL;Luminanciazaj-csökkentés +TP_LUMADENOISE_RADIUS;Sugár +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_FULLSIZE;Képméret: +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 +ZOOMBAR_DETAIL;Részlet nézet +ZOOMBAR_HUGE;Nagyobb +ZOOMBAR_LARGE;Nagy +ZOOMBAR_NORMAL;Normál +ZOOMBAR_PREVIEW;Előnézet +ZOOMBAR_SCALE;Kicsinyítés +ZOOMBAR_SMALL;KicsiHISTOGRAM_BUTTON_B;B +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;(Új) lupe megnyitása +ZOOMPANEL_ZOOM100;Nagyítás 100%-ra 1 +ZOOMPANEL_ZOOMFITSCREEN;Képernyő méretéhez igazítás F +ZOOMPANEL_ZOOMIN;Nagyítás + +ZOOMPANEL_ZOOMOUT;Kicsinyítés - + +#00 Magyar +#01 RT 3.0 alpha 1 rev. 597:fb291bf74c by Dr. Gyurkó M. 'dualon' Dávid + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!EXTPROGTARGET_1;raw +!EXTPROGTARGET_2;queue-processed +!FILEBROWSER_EXTPROGMENU;Open with +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!GENERAL_WARNING;Warning +!HISTOGRAM_TOOLTIP_FULL;Toggle full or scaled histogram +!HISTORY_MSG_167;B&W Toning +!HISTORY_MSG_168;'Cc' curve +!HISTORY_MSG_169;'Ch' curve +!HISTORY_MSG_170;Vibrance - Curve +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue processed first. +!MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 8 +!MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 0 +!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. +!PREFERENCES_MENUGROUPEXTPROGS;Group "Open with" +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing Profile Saved +!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\nthe 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_CROP_GTFRAME;Frame +!TP_ICM_PREFERREDPROFILE;Preferred DCP profile +!TP_ICM_PREFERREDPROFILE_1;Daylight +!TP_ICM_PREFERREDPROFILE_2;Tungsten +!TP_ICM_PREFERREDPROFILE_3;Fluorescent +!TP_ICM_PREFERREDPROFILE_4;Flash +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid Color Shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space\nand apply Munsell correction +!TP_LABCURVE_BWTONING;B&W Toning +!TP_LABCURVE_BWTONING_TIP;With B&W Toning option enabled, the Lab Chromaticity, Cc and Ch curves are not in effect.\nToning can be achieved using the a and b curves +!TP_LABCURVE_CHROMATICITY;Chromaticity +!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 the Chromaticity +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to the Hue +!TP_LABCURVE_RSTPROTECTION;Red and Skin Tones Protection +!TP_LENSPROFILE_FILEDLGFILTERLCP;Lens correction files +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;Use CA correction +!TP_LENSPROFILE_USEDIST;Use distortion correction +!TP_LENSPROFILE_USEVIGN;Use vignette correction +!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 the Hue +!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 diff --git a/rtdata/languages/Nederlands b/rtdata/languages/Nederlands new file mode 100644 index 000000000..44aea88bb --- /dev/null +++ b/rtdata/languages/Nederlands @@ -0,0 +1,1231 @@ +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 +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_DIALOGLABEL;Exif-filter +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_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 +FILEBROWSER_ADDDELTEMPLATE;Voeg sjablonen toe of verwijder... +FILEBROWSER_APPLYPROFILE;Pas profiel toe +FILEBROWSER_APPLYPROFILE_PARTIAL;Pas profiel toe (gedeeltelijk) +FILEBROWSER_ARRANGEMENTHINT;Verticale/horizontale uitlijning miniaturen +FILEBROWSER_AUTODARKFRAME;Automatisch donkerframe +FILEBROWSER_AUTOFLATFIELD;Selecteer automatisch vlakveldopname +FILEBROWSER_BROWSEPATHBUTTONHINT;Klik om te navigeren naar het gekozen pad +FILEBROWSER_BROWSEPATHHINT;Typ pad bestandslocatie\nCtrl-o Zet focus\nEnter, Ctrl-Enter Ga naar bestandslocatie;\nPad snelkoppelingen:\n~ Standaardmap ('home') \n! Afbeeldingenmap +FILEBROWSER_CACHECLEARFROMFULL;Verwijder uit cache - volledig +FILEBROWSER_CACHECLEARFROMPARTIAL;Verwijder uit cache - gedeeltelijk +FILEBROWSER_CACHE;Cache +FILEBROWSER_CLEARPROFILE;Verwijder profiel +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_EXIFFILTERAPPLYHINT;Pas Exif-filter toe op bestandsnavigator +FILEBROWSER_EXIFFILTERAPPLY;Activeer +FILEBROWSER_EXIFFILTERLABEL;Exif-filter +FILEBROWSER_EXIFFILTERSETTINGSHINT;Stel Exif-filter in +FILEBROWSER_EXIFFILTERSETTINGS;Stel in +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_PARTIALPASTEPROFILE;Gedeeltelijk plakken +FILEBROWSER_PASTEPROFILE;Plak profiel +FILEBROWSER_POPUPCANCELJOB;Verwijder uit verwerkingsrij +FILEBROWSER_POPUPCOLORLABEL0;Label: Geen +FILEBROWSER_POPUPCOLORLABEL1;Label: Rood +FILEBROWSER_POPUPCOLORLABEL2;Label: Geel +FILEBROWSER_POPUPCOLORLABEL3;Label: Groen +FILEBROWSER_POPUPCOLORLABEL4;Label: Blauw +FILEBROWSER_POPUPCOLORLABEL5;Label: Paars +FILEBROWSER_POPUPCOLORLABEL;Kleur label +FILEBROWSER_POPUPCOPYTO;Kopieer naar... +FILEBROWSER_POPUPFILEOPERATIONS;Bestandsbewerkingen +FILEBROWSER_POPUPMOVEEND;Naar eind van verwerkingsrij +FILEBROWSER_POPUPMOVEHEAD;Naar begin verwerkingsrij +FILEBROWSER_POPUPMOVETO;Verplaats naar... +FILEBROWSER_POPUPOPEN;Open +FILEBROWSER_POPUPPROCESSFAST;Plaats in verwerkingsrij voor Snelle Export +FILEBROWSER_POPUPPROCESS;Plaats in verwerkingsrij +FILEBROWSER_POPUPPROFILEOPERATIONS;Profielbewerkingen +FILEBROWSER_POPUPRANK1;Noteer met 1 ster +FILEBROWSER_POPUPRANK2;Noteer met 2 sterren +FILEBROWSER_POPUPRANK3;Noteer met 3 sterren +FILEBROWSER_POPUPRANK4;Noteer met 4 sterren +FILEBROWSER_POPUPRANK5;Noteer met 5 sterren +FILEBROWSER_POPUPREMOVEINCLPROC;Verwijder (met bestand in verwerkingsrij) +FILEBROWSER_POPUPREMOVESUBMENU;Verwijder +FILEBROWSER_POPUPREMOVE;Verwijder van bestandssysteem +FILEBROWSER_POPUPRENAME;Hernoem +FILEBROWSER_POPUPSELECTALL;Alles selecteren +FILEBROWSER_POPUPTRASH;Verplaats naar prullenbak +FILEBROWSER_POPUPUNRANK;Verwijder sternotering +FILEBROWSER_POPUPUNTRASH;Haal terug uit prullenbak +FILEBROWSER_PROCESSINGSETTINGSHINT;Kies bestandsformaat en doelmap +FILEBROWSER_PROCESSINGSETTINGS;Instellingen +FILEBROWSER_QUERYBUTTONHINT;Wis zoekopdracht +FILEBROWSER_QUERYHINT;Typ een deel van de bestandsnaam \nCtrl-f Zet focus;\nEnter Zoeken +FILEBROWSER_QUERYLABEL; Zoeken: +FILEBROWSER_RENAMEDLGLABEL;Hernoem bestand +FILEBROWSER_RENAMEDLGMSG;Hernoem bestand "%1" naar: +FILEBROWSER_SELECTDARKFRAME;Selecteer donkerframe... +FILEBROWSER_SELECTFLATFIELD;Kies vlakveldopname... +FILEBROWSER_SHOWCOLORLABEL1HINT;Toon afbeeldingen met label Rood Alt-1 +FILEBROWSER_SHOWCOLORLABEL2HINT;Toon afbeeldingen met label Geel Alt-2 +FILEBROWSER_SHOWCOLORLABEL3HINT;Toon afbeeldingen met label Groen Alt-3 +FILEBROWSER_SHOWCOLORLABEL4HINT;Toon afbeeldingen met label Blauw Alt-4 +FILEBROWSER_SHOWCOLORLABEL5HINT;Toon afbeeldingen met label Paars Alt-5 +FILEBROWSER_SHOWDIRHINT;Toon alle foto's in map +FILEBROWSER_SHOWEDITEDHINT;Toon bewerkte afbeeldingen 7 +FILEBROWSER_SHOWEDITEDNOTHINT;Toon niet-bewerkte afbeeldingen 6 +FILEBROWSER_SHOWEXIFINFO;Toon EXIF-info +FILEBROWSER_SHOWQUEUEHINT;Toon inhoud verwerkingsrij +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 afbeeldingen Alt-7 +FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Toon niet-opgeslagen/verwerkte afbeeldingen Alt-6 +FILEBROWSER_SHOWTRASHHINT;Toon inhoud prullenbak +FILEBROWSER_SHOWUNCOLORHINT;Toon afbeeldingen zonder kleurlabel Alt-` +FILEBROWSER_SHOWUNRANKHINT;Toon foto's zonder sternotering +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_USETEMPLATE;Gebruik sjabloon: +FILEBROWSER_ZOOMINHINT;Groter +FILEBROWSER_ZOOMOUTHINT;Kleiner +GENERAL_ABOUT;Over RawTherapee +GENERAL_AFTER;Na +GENERAL_BEFORE;Voor +GENERAL_CANCEL;Annuleren +GENERAL_DISABLED;Gedeactiveerd +GENERAL_DISABLE;Deactiveren +GENERAL_ENABLED;Geactiveerd +GENERAL_ENABLE;Activeer +GENERAL_FILE;Bestand +GENERAL_HIGH_QUALITY;Hoge kwaliteit +GENERAL_LANDSCAPE;Landschap +GENERAL_LOAD;Laden +GENERAL_NA;nvt. +GENERAL_NONE;Geen +GENERAL_NO;Nee +GENERAL_OK;OK +GENERAL_PORTRAIT;Portret +GENERAL_SAVE;Opslaan +GENERAL_UNCHANGED;(Onveranderd) +GENERAL_YES;Ja +HISTOGRAM_BUTTON_BAR;RGB +HISTOGRAM_BUTTON_B;B +HISTOGRAM_BUTTON_G;G +HISTOGRAM_BUTTON_L;L +HISTOGRAM_BUTTON_RAW;Raw +HISTOGRAM_BUTTON_R;R +HISTOGRAM_LABEL;Histogram +HISTOGRAM_TOOLTIP_BAR;Toon/verberg RGB-indicatie\nRechtermuisklik op foto om te starten/stoppen +HISTOGRAM_TOOLTIP_B;Toon/verberg blauw 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 +HISTORY_MSG_12;Automatische belichting +HISTORY_MSG_13;Drempel +HISTORY_MSG_14;LAB: helderheid +HISTORY_MSG_15;LAB: contrast +HISTORY_MSG_16;Lum: schaduwen +HISTORY_MSG_17;Lum: compr. hoge lichten +HISTORY_MSG_18;Lum: schaduwcompressie +HISTORY_MSG_19;Luminantiecurve +HISTORY_MSG_20;Verscherping +HISTORY_MSG_21;Straal verscherping +HISTORY_MSG_22;Hoeveelheid verscherping +HISTORY_MSG_23;Drempel verscherping +HISTORY_MSG_24;Alleen randen verscherpen +HISTORY_MSG_25;Straal randverscherping +HISTORY_MSG_26;Tolerantie randverscherping +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;Vermijd kleuroversturing +HISTORY_MSG_35;Verzadigingsbegrenzer +HISTORY_MSG_36;Verzadigingslimiet +HISTORY_MSG_37;Kleurversterking +HISTORY_MSG_38;Witbalansmethode +HISTORY_MSG_39;Kleurtemperatuur +HISTORY_MSG_40;Groentint WB +HISTORY_MSG_41;Kleurverschuiving A +HISTORY_MSG_42;Kleurverschuiving B +HISTORY_MSG_43;Ruisonderdrukking luminantie +HISTORY_MSG_44;Straal lum. ruisonderdrukking +HISTORY_MSG_45;Randtolerantie lum. ruisonderdrukking +HISTORY_MSG_46;Ruisonderdrukking kleur +HISTORY_MSG_47;Straal kleurruisonderdrukking +HISTORY_MSG_48;Randtolerantie kleurruisonderdrukking +HISTORY_MSG_49;Randgevoeligheid kleurruisonderdrukking +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;Rotatie +HISTORY_MSG_62;Corrigeer lensvervorming +HISTORY_MSG_63;Snapshot +HISTORY_MSG_64;Afbeelding bijsnijden +HISTORY_MSG_65;C/A-correctie +HISTORY_MSG_66;Repareer hoge lichten +HISTORY_MSG_67;Repareer hoge lichten, hoeveelheid +HISTORY_MSG_68;Repareer hoge lichten, methode +HISTORY_MSG_69;Kleurwerkruimte +HISTORY_MSG_70;Uitvoerkleurruimte +HISTORY_MSG_71;Invoerkleurruimte +HISTORY_MSG_72;Vignetteringscorrectie +HISTORY_MSG_73;Kanaalmixer +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;Waveletcoëfficienten +HISTORY_MSG_86;Wavelet-equalizer +HISTORY_MSG_87;Zout&peper-ruisonderdrukking +HISTORY_MSG_88;Zout&peper-drempel +HISTORY_MSG_89;Ruisonderdrukking +HISTORY_MSG_90;Luminantie +HISTORY_MSG_91;Chrominantie +HISTORY_MSG_92;Gamma +HISTORY_MSG_93;Detailcontrast waarde +HISTORY_MSG_94;Detailcontrast +HISTORY_MSG_95;LAB: verzadiging +HISTORY_MSG_96;'a'-curve +HISTORY_MSG_97;'b'-curve +HISTORY_MSG_98;Demozaïekproces +HISTORY_MSG_99;Voorbewerking +HISTORY_MSG_100;RGB-verzadiging +HISTORY_MSG_101;HSV EQ: tint +HISTORY_MSG_102;HSV EQ: verzadiging +HISTORY_MSG_103;HSV EQ: waarde +HISTORY_MSG_104;HSV-equalizer +HISTORY_MSG_105;Randverzachting +HISTORY_MSG_106;Randverzachting radius +HISTORY_MSG_107;Randverzachting drempel +HISTORY_MSG_108;Drempel compr. hoge lichten +HISTORY_MSG_109;Hoogte en breedte +HISTORY_MSG_110;Herschalen van: +HISTORY_MSG_111;Vermijd kleuroversturing +HISTORY_MSG_112;Verzadigingsbegrenzer +HISTORY_MSG_113;Verzadigingslimiet +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 luminantie +HISTORY_MSG_132;Ruisonderdrukking chrominantie +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 verscherpen - herhalingen +HISTORY_MSG_143;Randen verscherpen - hoeveelheid +HISTORY_MSG_144;Microcontrast - hoeveelheid +HISTORY_MSG_145;Microcontrast - uniformiteit +HISTORY_MSG_146;Randen verscherpen +HISTORY_MSG_147;Randen verscherpen - alleen luminantie +HISTORY_MSG_148;Microcontrast +HISTORY_MSG_149;Microcontrast - 3x3 matrix +HISTORY_MSG_150;Nabewerking demozaïek artefact/ruisonderdrukking +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_NEWSNAPSHOTAS;Als... +HISTORY_NEWSNAPSHOT;Nieuw +HISTORY_NEWSSDIALOGLABEL;Naam snapshot: +HISTORY_NEWSSDIALOGTITLE;Voeg nieuw snapshot toe +HISTORY_SETTO;Instellen +HISTORY_SNAPSHOTS;Snapshots +HISTORY_SNAPSHOT;Nieuw +ICMPANEL_FILEDLGFILTERANY;Alle bestanden +ICMPANEL_FILEDLGFILTERICM;ICC-profielbestanden +ICMPANEL_GAMMABEFOREINPUT;Profiel past gamma toe +ICMPANEL_INPUTCAMERA;Camera +ICMPANEL_INPUTCUSTOM;Handmatig +ICMPANEL_INPUTDLGLABEL;Selecteer invoer-ICC-profiel... +ICMPANEL_INPUTEMBEDDED;Gebruik ingebed profiel indien mogelijk +ICMPANEL_INPUTPROFILE;Invoerprofiel +ICMPANEL_NOICM;Geen ICM: sRGB-uitvoer +ICMPANEL_OUTPUTDLGLABEL;Selecteer uitvoer-ICC-profiel... +ICMPANEL_OUTPUTPROFILE;Uitvoerprofiel +ICMPANEL_SAVEREFERENCE;Bewaar referentiefoto tbv. profiling +ICMPANEL_WORKINGPROFILE;Werkprofiel +IMAGEAREA_DETAILVIEW;Detailvenster +IPTCPANEL_AUTHORHINT;Naam van de maker van het object, bijv. schrijver, fotograaf of ontwerper (By-line) +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_EXIT;Afsluiten +MAIN_BUTTON_FULLSCREEN;Volledig scherm +MAIN_BUTTON_PREFERENCES;Voorkeuren +MAIN_BUTTON_PUTTOQUEUE;Plaats in verwerkingsrij +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Plaats huidige foto in verwerkingsrij Ctrl+Q +MAIN_BUTTON_QUEUE;Plaats in verwerkingsrij +MAIN_BUTTON_SAVEAS;Als... +MAIN_BUTTON_SAVE;Bewaar foto +MAIN_BUTTON_SAVE_TOOLTIP;Bewaar huidige foto Ctrl+S +MAIN_BUTTON_SENDTOEDITOR;Stuur naar fotoprogramma +MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Stuur huidige foto naar extern fotobewerkingsprogramma Ctrl+E +MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Toon/verberg alle zijpanelen m +MAIN_BUTTON_UNFULLSCREEN;Verlaat volledig scherm +MAIN_FRAME_BATCHQUEUE;Verwerkingsrij +MAIN_FRAME_BATCHQUEUE_TOOLTIP; Verwerkingsrij Ctrl-F3 +MAIN_FRAME_EDITOR;Fotobewerker +MAIN_FRAME_EDITOR_TOOLTIP; Bewerking Ctrl-F4 +MAIN_FRAME_FILEBROWSER;Bestandsnavigator +MAIN_FRAME_FILEBROWSER_TOOLTIP; Bestandsnavigator 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;Bestandsnaam ontbreekt! +MAIN_MSG_ERRORDURINGIMAGESAVING;Fout tijdens opslaan foto +MAIN_MSG_EXITJOBSINQUEUEINFO;Foto's in de verwerkingsrij zullen niet verwerkt worden bij afsluiten. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Weet u zeker dat u wilt stoppen? De verwerkingsrij bevat nog foto's. +MAIN_MSG_JOBSINQUEUE;Bewerking(en) in de wachtrij +MAIN_MSG_NAVIGATOR;Navigator +MAIN_MSG_PLACES;Locaties +MAIN_MSG_QOVERWRITE;Wilt u het bestand overschrijven? +MAIN_TAB_BASIC;Grondwaarde +MAIN_TAB_COLOR;Kleur +MAIN_TAB_COLOR_TOOLTIP;Alt-c +MAIN_TAB_DETAIL;Detail +MAIN_TAB_DETAIL_TOOLTIP;Alt-d +MAIN_TAB_DEVELOP;Ontwikkel +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPORT; Exporteren +MAIN_TAB_EXPOSURE;Belichting +MAIN_TAB_EXPOSURE_TOOLTIP;Alt-e +MAIN_TAB_FILTER;Filter +MAIN_TAB_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_METADATA_TOOLTIP;Alt-m +MAIN_TAB_RAW;RAW +MAIN_TAB_RAW_TOOLTIP;Alt-r +MAIN_TAB_TAGGING;Tags +MAIN_TAB_TRANSFORM;Transformeer +MAIN_TAB_TRANSFORM_TOOLTIP;Alt-t +MAIN_TOGGLE_BEFORE_AFTER;V-N +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_HIDEFP;Toon/verberg onderpaneel (bestandsnavigator, sneltoets F) +MAIN_TOOLTIP_HIDEHP;Toon/verberg linkerpaneel (geschiedenis, sneltoets H) +MAIN_TOOLTIP_INDCLIPPEDH;Overbelichtingsindicatie +MAIN_TOOLTIP_INDCLIPPEDS;Onderbelichtingsindicatie +MAIN_TOOLTIP_PREFERENCES;Voorkeuren en instellingen +MAIN_TOOLTIP_PREVIEWB;Bekijk het Blauwe kanaal.\nSnelkoppeling: b +MAIN_TOOLTIP_PREVIEWFOCUSMASK;Bekijk het Focus Masker.\nSnelkoppeling: 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.\nSnelkoppeling: g +MAIN_TOOLTIP_PREVIEWL;Bekijk de Luminositeit.\nSnelkoppeling: v\n\n0.299*R + 0.587*G + 0.114*B +MAIN_TOOLTIP_PREVIEWR;Bekijk het Rode kanaal.\nSnelkoppeling: r +MAIN_TOOLTIP_QINFO;Beknopte fotogegevens +MAIN_TOOLTIP_SAVEAS;Bewaar foto in andere map/ander formaat +MAIN_TOOLTIP_SAVE;Bewaar foto in standaardmap +MAIN_TOOLTIP_SHOWHIDELP1;Toon/verberg linkerpaneel l +MAIN_TOOLTIP_SHOWHIDERP1;Toon/verberg rechterpaneel Alt-l +MAIN_TOOLTIP_SHOWHIDETP1;Toon/verberg bovenste paneel 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_NA;x = n/b, y = n/b +PARTIALPASTE_BASICGROUP;Basisinstellingen +PARTIALPASTE_CACORRECTION;C/A-correctie +PARTIALPASTE_CHANNELMIXER;Kanaalmixer +PARTIALPASTE_COARSETRANS;90 graden roteren/spiegelen +PARTIALPASTE_COLORBOOST;Kleurversterking +PARTIALPASTE_COLORDENOISE;Ruisonderdrukking kleur +PARTIALPASTE_COLORGROUP;Kleurgerelateerde instellingen +PARTIALPASTE_COLORMIXER;Kleurenmixer +PARTIALPASTE_COLORSHIFT;Kleuroversturing +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_HLRECONSTRUCTION;Repareer hoge lichten +PARTIALPASTE_HLRECOVERYAMOUNT;Hoge lichten comprimeren: hoeveelheid +PARTIALPASTE_HLRECOVERYTHRESHOLD;Hoge lichten comprimeren: drempel +PARTIALPASTE_HLRECOVERY;Repareer hoge lichten +PARTIALPASTE_HSVEQUALIZER;HSV-equalizer +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_LUMACURVE;Luminantiecurve +PARTIALPASTE_LUMADENOISE;Ruisonderdrukking luminantie +PARTIALPASTE_LUMINANCEGROUP;Instellingen luminantie +PARTIALPASTE_METAICMGROUP;Metadata/ICM-instellingen +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_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_WAVELETEQUALIZER;Wavelet-equalizer +PARTIALPASTE_WHITEBALANCE;Witbalans +PREFERENCES_ADD;Voeg toe +PREFERENCES_APPLNEXTSTARTUP;herstart vereist +PREFERENCES_AUTOMONPROFILE;Gebruik automatisch het standaard monitorprofiel \nvan het besturingsysteem +PREFERENCES_BATCH_PROCESSING;Batch-verwerking +PREFERENCES_BEHAVIOR;Gedrag +PREFERENCES_BLINKCLIPPED;Knipper bij over-/onderbelichting +PREFERENCES_CACHECLEARALL;Wis alles +PREFERENCES_CACHECLEARPROFILES;Wis profielen +PREFERENCES_CACHECLEARTHUMBS;Wis miniaturen +PREFERENCES_CACHEFORMAT1;RawTherapee (sneller, beter) +PREFERENCES_CACHEFORMAT2;JPEG (minder schijfruimte) +PREFERENCES_CACHEMAXENTRIES;Maximaal aantal elementen in cache +PREFERENCES_CACHEOPTS;Cache-opties +PREFERENCES_CACHESTRAT1;Sneller, meer geheugenbeslag +PREFERENCES_CACHESTRAT2;Langzamer, minder geheugenbeslag +PREFERENCES_CACHESTRAT;Cache-strategie +PREFERENCES_CACHETHUMBFORM;Miniatuurformaat cache +PREFERENCES_CACHETHUMBHEIGHT;Maximale hoogte miniaturen +PREFERENCES_CLEARDLG_LINE1;Cache legen... +PREFERENCES_CLEARDLG_LINE2;Dit kan even duren. +PREFERENCES_CLEARDLG_TITLE;Momentje svp. +PREFERENCES_CLIPPINGIND;Indicatie over-/onderbelichting +PREFERENCES_CMETRICINTENT;Bedoelde colorimetrie +PREFERENCES_CUSTPROFBUILDHINT;Programma (of script) dat wordt aangeroepen om een initieel profiel voor een raw-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] +PREFERENCES_CUSTPROFBUILDPATH;Pad naar programma of script +PREFERENCES_CUSTPROFBUILD;Eigen/externe profielgenerator +PREFERENCES_CUTOVERLAYBRUSH;Kleur uitsnedemasker +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_DEMOSAICINGALGO;Demozaïek-algoritme +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_FORIMAGE;Voor niet-RAW-bestanden +PREFERENCES_FORRAW;Voor RAW-bestanden +PREFERENCES_GIMPPATH;Installatiemap GIMP +PREFERENCES_GTKTHEME;GTK standaard +PREFERENCES_HINT;Voorbeeld +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_LIVETHUMBNAILS;Live-miniaturen (langzamer) +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_OUTDIRHINT;U kunt de volgende formaten gebruiken:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nDeze formaten hebben betrekking op de mappen en submappen 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\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_OUTDIRTEMPLATEHINT;U kunt de volgende formaten gebruiken:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nDeze formaten hebben betrekking op de mappen en submappen 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=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\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_SELECTFONT;Kies lettertype +PREFERENCES_SELECTICCDIRDLG;Selecteer ICC-profielmap... +PREFERENCES_SELECTLANG;Selecteer taal +PREFERENCES_SELECTMONITORPROFDLG;Selecteer ICC-profielmap van de monitor... +PREFERENCES_SELECTTHEME;Kies thema +PREFERENCES_SET;Activeer +PREFERENCES_SHOWBASICEXIF;Toon standaard Exif-info +PREFERENCES_SHOWDATETIME;Toon datum en tijd +PREFERENCES_SHOWEXPOSURECOMPENSATION;Toon belichtingscompensatie +PREFERENCES_SHOWONLYRAW;Toon alleen RAW-bestanden +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). Windows: \ngebruik 'SystemDefault', 'SystemAsterisk', 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_OUTPUT;Uitvoeropties +PREFERENCES_TAB_SOUND;Geluiden +PREFERENCES_THUMBSIZE;Miniatuurgrootte +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_USESYSTEMTHEME; Gebruik systeemthema +PREFERENCES_WORKFLOW;Layout +PROFILEPANEL_COPYPPASTE;Te kopiëren parameters +PROFILEPANEL_FILEDLGFILTERANY;Alle bestanden +PROFILEPANEL_FILEDLGFILTERPP;Profielen +PROFILEPANEL_LABEL;Profielen +PROFILEPANEL_LOADDLGLABEL;Kies profiel... +PROFILEPANEL_LOADPPASTE;Te laden parameters +PROFILEPANEL_PASTEPPASTE;Te plakken parameters +PROFILEPANEL_PCUSTOM;Handmatig +PROFILEPANEL_PFILE;Uit bestand +PROFILEPANEL_PLASTPHOTO;Laatste afbeelding +PROFILEPANEL_PLASTSAVED;Laatst opgeslagen +PROFILEPANEL_PROFILE;Profiel +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_BADPIXELS;Slechte pixels... +PROGRESSBAR_CACORRECTION;CA-correctie... +PROGRESSBAR_DARKFRAME;Donkerframe... +PROGRESSBAR_DECODING;Laden RAW-bestand... +PROGRESSBAR_DEMOSAICING;Demozaïek-algoritme... +PROGRESSBAR_GREENEQUIL;Groenbalans... +PROGRESSBAR_LINEDENOISE;Lijnruisfilter... +PROGRESSBAR_LOADINGTHUMBS;Miniaturen laden... +PROGRESSBAR_LOADING;Afbeelding laden... +PROGRESSBAR_LOADJPEG;Laden JPEG-bestand... +PROGRESSBAR_LOADPNG;Laden PNG-bestand... +PROGRESSBAR_LOADTIFF;Laden TIFF-bestand... +PROGRESSBAR_PROCESSING;Foto verwerken... +PROGRESSBAR_READY;Gereed. +PROGRESSBAR_SAVEJPEG;Opslaan JPEG-bestand... +PROGRESSBAR_SAVEPNG;Opslaan PNG-bestand... +PROGRESSBAR_SAVETIFF;Opslaan TIFF-bestand... +PROGRESSDLG_LOADING;Foto laden... +PROGRESSDLG_PROCESSING;Foto verwerken... +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profiel veranderd in bestandsnavigator +PROGRESSDLG_SAVING;Foto opslaan... +QINFO_FOCALLENGTH;Brandpuntsafstand +QINFO_ISO;ISO +QINFO_LENS;Objectief +QINFO_NOEXIF;Exif-gegevens niet beschikbaar. +SAVEDLG_AUTOSUFFIX;Voeg automatisch ophogend nummer (-1, -2..) toe als bestand al bestaat +SAVEDLG_FILEFORMAT;Bestandstype +SAVEDLG_JPEGQUAL;JPEG-kwaliteit +SAVEDLG_JPGFILTER;JPEG-bestanden +SAVEDLG_PNGCOMPR;PNG-compressie +SAVEDLG_PNGFILTER;PNG-bestanden +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_TIFFFILTER;TIFF-bestanden +SAVEDLG_TIFFUNCOMPRESSED;Geen compressie +TOOLBAR_TOOLTIP_CROP;Bijsnijden (sneltoets C) +TOOLBAR_TOOLTIP_HAND;Sleepgereedschap (sneltoets N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Rechte lijn bepalen (sneltoets S) +TOOLBAR_TOOLTIP_WB;Witbalans (sneltoets W) +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;Kanaalmixer +TP_CHMIXER_RED;Rood +TP_CHROMATABERR_LABEL;Chromatische aberratie +TP_COARSETRAF_DEGREE;graden: +TP_COARSETRAF_TOOLTIP_HFLIP;Horizontaal spiegelen +TP_COARSETRAF_TOOLTIP_ROTLEFT;Linksom roteren +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rechtsom roteren +TP_COARSETRAF_TOOLTIP_VFLIP;Verticaal spiegelen +TP_COLORBOOST_ACHANNEL;Kanaal A +TP_COLORBOOST_AMOUNT;Hoeveelheid +TP_COLORBOOST_AVOIDCOLORCLIP;Vermijd kleuroversturing +TP_COLORBOOST_BCHANNEL;Kanaal B +TP_COLORBOOST_CHAB;A & B +TP_COLORBOOST_CHANNEL;Kanaal +TP_COLORBOOST_CHSEPARATE;Scheiden +TP_COLORBOOST_ENABLESATLIMITER;Activeer verzadigingsbegrenzer +TP_COLORBOOST_LABEL;Kleurversterking +TP_COLORBOOST_SATLIMIT;Verzadigingslimiet +TP_COLORDENOISE_EDGESENSITIVE;Randgevoeligheid +TP_COLORDENOISE_EDGETOLERANCE;Randtolerantie +TP_COLORDENOISE_LABEL;Ruisonderdrukking op kleur +TP_COLORDENOISE_RADIUS;Straal +TP_COLORSHIFT_BLUEYELLOW;Blauw-Geel +TP_COLORSHIFT_GREENMAGENTA;Groen-Magenta +TP_COLORSHIFT_LABEL;Kleurverschuiving +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;Verhouding: +TP_CROP_GTDIAGONALS;Diagonaalmethode +TP_CROP_GTEPASSPORT;Biometrisch paspoort +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;H +TP_CROP_LABEL;Bijsnijden +TP_CROP_PPI;PPI= +TP_CROP_SELECTCROP;Selecteer gebied +TP_CROP_W;B +TP_CROP_X;X +TP_CROP_Y;Y +TP_DARKFRAME_AUTOSELECT;Automatische selectie +TP_DARKFRAME_LABEL;Donkerframe +TP_DEFRINGE_LABEL;Verzachten +TP_DEFRINGE_RADIUS;Straal +TP_DEFRINGE_THRESHOLD;Drempel +TP_DETAIL_AMOUNT;Hoeveelheid +TP_DIRPYRDENOISE_CHROMA;Chrominantie +TP_DIRPYRDENOISE_GAMMA;Gamma +TP_DIRPYRDENOISE_LABEL;Ruisonderdrukking +TP_DIRPYRDENOISE_LUMA;Luminantie +TP_DIRPYREQUALIZER_LABEL;Detailcontrast +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 +TP_EPD_REWEIGHTINGITERATES;Herhaling +TP_EPD_SCALE;Schaal +TP_EPD_STRENGTH;Sterkte +TP_EQUALIZER_CONTRAST_MINUS;Contrast- +TP_EQUALIZER_CONTRAST_PLUS;Contrast+ +TP_EQUALIZER_FINEST;fijnste +TP_EQUALIZER_LABEL;Wavelet-equalizer +TP_EQUALIZER_LARGEST;grofste +TP_EQUALIZER_NEUTRAL;Neutraal +TP_EXPOSCORR_LABEL;RAW witpunt/zwartniveau +TP_EXPOSURE_AUTOLEVELS;Autom. niveaus +TP_EXPOSURE_AUTOLEVELS_TIP;Activeer automatische niveaus. +TP_EXPOSURE_BLACKLEVEL;Schaduwen +TP_EXPOSURE_BRIGHTNESS;Helderheid +TP_EXPOSURE_CLIP;Drempel +TP_EXPOSURE_CLIP_TIP;Het deel van de pixels dat moet worden gecomprimeerd bij gebruik van automatische niveaus. +TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Drempel herstel hoge lichten +TP_EXPOSURE_COMPRHIGHLIGHTS;Hoge lichten comprimeren +TP_EXPOSURE_COMPRSHADOWS;Schaduwcompressie +TP_EXPOSURE_CONTRAST;Contrast +TP_EXPOSURE_CURVEEDITOR;Tooncurve +TP_EXPOSURE_EXPCOMP;Belichtingscompensatie +TP_EXPOSURE_LABEL;Belichting +TP_EXPOSURE_SATURATION;Verzadiging +TP_EXPO_AFTER; Na interpolatie (voor RGB-conversie) +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_HLREC_BLEND;Mengen +TP_HLREC_CIELAB;CIELab-blending +TP_HLREC_COLOR;Kleurherstel +TP_HLREC_LABEL;Repareer hoge lichten +TP_HLREC_LUMINANCE;Lichtherstel +TP_HLREC_METHOD;Methode: +TP_HSVEQUALIZER1;Rood +TP_HSVEQUALIZER2;Geel +TP_HSVEQUALIZER3;Limoen +TP_HSVEQUALIZER4;Groen +TP_HSVEQUALIZER5;Lichtblauw +TP_HSVEQUALIZER6;Blauw +TP_HSVEQUALIZER7;Paars +TP_HSVEQUALIZER8;Magenta +TP_HSVEQUALIZER_CHANNEL;HSV-kanaal +TP_HSVEQUALIZER_HUE;Tint +TP_HSVEQUALIZER_LABEL;HSV-equalizer +TP_HSVEQUALIZER_NEUTRAL;Neutraal +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_FILEDLGFILTERANY;Alle bestanden +TP_ICM_FILEDLGFILTERICM;ICC-profielbestanden +TP_ICM_GAMMABEFOREINPUT;Profiel past gamma toe +TP_ICM_INPUTCAMERAICC;Camera standaard of ICC +TP_ICM_INPUTCAMERAICC_TOOLTIP;Gebruik RawTherapee's camera-specifieke DCP- of ICC-invoerprofiel 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 +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;ICM +TP_ICM_NOICM;Geen ICM: sRGB-uitvoer +TP_ICM_OUTPUTDLGLABEL;Selecteer uitvoer-ICC-profiel... +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_WORKINGPROFILE;Werkprofiel +TP_IMPULSEDENOISE_LABEL;Spot-ruisonderdrukking +TP_IMPULSEDENOISE_THRESH;Drempel +TP_LABCURVE_AVOIDCOLORCLIP;Vermijd kleuroversturing +TP_LABCURVE_BRIGHTNESS;Helderheid +TP_LABCURVE_CONTRAST;Contrast +TP_LABCURVE_CURVEEDITOR;Luminantiecurve +TP_LABCURVE_ENABLESATLIMITER;Activeer verzadigingsbegrenzer +TP_LABCURVE_LABEL;LAB-curves +TP_LABCURVE_SATLIMIT;Grens verzadiging +TP_LABCURVE_SATURATION;Verzadiging +TP_LENSGEOM_AUTOCROP;Automatisch bijsnijden +TP_LENSGEOM_FILL;Automatisch uitvullen +TP_LENSGEOM_LABEL;Objectief / Geometrie +TP_LUMACURVE_BLACKLEVEL;Schaduwen +TP_LUMACURVE_BRIGHTNESS;Helderheid +TP_LUMACURVE_COMPRHIGHLIGHTS;Hoge lichten comprimeren +TP_LUMACURVE_COMPRSHADOWS;Schaduwen comprimeren +TP_LUMACURVE_CONTRAST;Contrast +TP_LUMACURVE_CURVEEDITOR;Luminantiecurve +TP_LUMACURVE_LABEL;Luminantiecurve +TP_LUMADENOISE_EDGETOLERANCE;Randtolerantie +TP_LUMADENOISE_LABEL;Ruisonderdrukking op luminantie +TP_LUMADENOISE_RADIUS;Straal +TP_NEUTRAL;Neutraal +TP_NEUTRAL_TIP;Alle belichtingsinstellingen naar 0 +TP_PERSPECTIVE_HORIZONTAL;Horizontaal +TP_PERSPECTIVE_LABEL;Perspectief +TP_PERSPECTIVE_VERTICAL;Verticaal +TP_PREPROCESS_GREENEQUIL;Groenbalans +TP_PREPROCESS_HOTDEADPIXFILT;Filter hete/dode pixels +TP_PREPROCESS_HOTDEADPIXTHRESH;Drempel hete/dode pixels +TP_PREPROCESS_LABEL;Voorbewerking +TP_PREPROCESS_LINEDENOISE;Lijnruisfilter +TP_PREPROCESS_NO_FOUND;Niet gevonden +TP_RAWCACORR_AUTO;Automatische CA-correctie +TP_RAWCACORR_CABLUE;Blauw +TP_RAWCACORR_CARED;Rood +TP_RAWEXPOS_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_FALSECOLOR;Stapgrootte kleurfoutonderdrukking +TP_RAW_LABEL;Demozaïekproces +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_DOWNSCALEB;Neerschalen (beter) +TP_RESIZE_DOWNSCALEF;Neerschalen (sneller) +TP_RESIZE_FITBOX;Breedte en hoogte +TP_RESIZE_FULLIMAGE;Hele foto +TP_RESIZE_FULLSIZE;Volledige beeldgrootte: +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_RED;R +TP_ROTATE_AUTOCROP;Automatisch bijsnijden +TP_ROTATE_DEGREE;Graden +TP_ROTATE_FILL;Uitvullen +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 +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_USM;Onscherpmasker +TP_SHARPENMICRO_AMOUNT;Hoeveelheid +TP_SHARPENMICRO_LABEL;Microcontrast +TP_SHARPENMICRO_MATRIX;3×3-matrix ipv. 5×5 +TP_SHARPENMICRO_UNIFORMITY;Uniformiteit +TP_VIBRANCE_AVOIDCOLORSHIFT;Vermijd kleurverschuiving +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_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;Corrigeer vignettering +TP_VIGNETTING_RADIUS;Straal +TP_VIGNETTING_STRENGTH;Kracht +TP_WBALANCE_AUTO;Automatisch +TP_WBALANCE_CAMERA;Camera +TP_WBALANCE_CLOUDY;Bewolkt +TP_WBALANCE_CUSTOM;Handmatig +TP_WBALANCE_DAYLIGHT;Daglicht (zonnig) +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) +ZOOMBAR_DETAIL;Detailvenster +ZOOMBAR_HUGE;Groter +ZOOMBAR_LARGE;Groot +ZOOMBAR_NORMAL;Normaal +ZOOMBAR_PREVIEW;Afbeelding +ZOOMBAR_SCALE;Schaal +ZOOMBAR_SMALL;Klein +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;Open (nieuw) detailvenster +ZOOMPANEL_ZOOM100;Zoom naar 100% +ZOOMPANEL_ZOOMFITSCREEN;Passend in venster +ZOOMPANEL_ZOOMIN;Zoom in +ZOOMPANEL_ZOOMOUT;Zoom uit + +#00 Nederlands +#01 26.12.2007: door Rens Duijsens en Brent Huisman +#02 14.03.2008: updated by reggybe +#03 01.02.2009: updated to RT2.4-RC by paul.matthijsse +#04 02-05-2010: updated to rt3a1 by paul.matthijsse +#05 03-03-2011: updated to rt3a2 by paul.matthijsse +#06 10-10-2011: updated to rt4.0 by wim ter meer +#07 28-11-11: updated by pm +#08 17-05-2012: updated to rt4.8 by wim ter meer + + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!EXTPROGTARGET_1;raw +!EXTPROGTARGET_2;queue-processed +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!GENERAL_WARNING;Warning +!HISTOGRAM_TOOLTIP_FULL;Toggle full or scaled histogram +!HISTORY_MSG_167;B&W Toning +!HISTORY_MSG_168;'Cc' curve +!HISTORY_MSG_169;'Ch' curve +!HISTORY_MSG_170;Vibrance - Curve +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue processed first. +!MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 8 +!MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 0 +!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. +!PREFERENCES_MENUGROUPEXTPROGS;Group "Open with" +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing Profile Saved +!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\nthe 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_CROP_GTFRAME;Frame +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid Color Shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space\nand apply Munsell correction +!TP_LABCURVE_BWTONING;B&W Toning +!TP_LABCURVE_BWTONING_TIP;With B&W Toning option enabled, the Lab Chromaticity, Cc and Ch curves are not in effect.\nToning can be achieved using the a and b curves +!TP_LABCURVE_CHROMATICITY;Chromaticity +!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 the Chromaticity +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to the Hue +!TP_LABCURVE_RSTPROTECTION;Red and Skin Tones Protection +!TP_LENSPROFILE_FILEDLGFILTERLCP;Lens correction files +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;Use CA correction +!TP_LENSPROFILE_USEDIST;Use distortion correction +!TP_LENSPROFILE_USEVIGN;Use vignette correction +!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 the Hue +!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 diff --git a/rtdata/languages/Norsk BM b/rtdata/languages/Norsk BM new file mode 100644 index 000000000..cba5cad73 --- /dev/null +++ b/rtdata/languages/Norsk BM @@ -0,0 +1,1208 @@ +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_DIALOGLABEL;Exif Filter +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_ARRANGEMENTHINT;Bytt mellom vertikal/horisontal oppstilling av thumbnails +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_EXIFFILTERAPPLYHINT;Skru på/av exif filter i filleseren +FILEBROWSER_EXIFFILTERAPPLY;Legg til +FILEBROWSER_EXIFFILTERLABEL;Exif Filter +FILEBROWSER_EXIFFILTERSETTINGSHINT;Forandre opsettet i exif filteret +FILEBROWSER_EXIFFILTERSETTINGS;Oppsett +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_POPUPRANK1;Rang 1 +FILEBROWSER_POPUPRANK2;Rang 2 +FILEBROWSER_POPUPRANK3;Rang 3 +FILEBROWSER_POPUPRANK4;Rang 4 +FILEBROWSER_POPUPRANK5;Rang 5 +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_PROCESSINGSETTINGSHINT;Sett filformat og folderbane +FILEBROWSER_PROCESSINGSETTINGS;Innstillinger +FILEBROWSER_RENAMEDLGLABEL;Bytt filnavn +FILEBROWSER_RENAMEDLGMSG;Bytt filnavn "%1" til: +FILEBROWSER_SHOWDIRHINT;Vis alle bildene i folderen +FILEBROWSER_SHOWQUEUEHINT;Vis innholdet i prosesseringskøen +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_LOAD;Åpne +GENERAL_NA;n/a +GENERAL_NO;Nei +GENERAL_OK;Ok +GENERAL_PORTRAIT;Portrett +GENERAL_SAVE;Lagre +GENERAL_YES;Ja +HISTOGRAM_LABEL;Histogram +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_NEWSNAPSHOTAS;Som... +HISTORY_NEWSNAPSHOT;Nytt b.m +HISTORY_NEWSSDIALOGLABEL;Navn på bokmerket: +HISTORY_NEWSSDIALOGTITLE;Opprett nytt bogmerke +HISTORY_SETTO;Inntil +HISTORY_SNAPSHOTS;Bokmerker +HISTORY_SNAPSHOT;Bokmerke +ICMPANEL_FILEDLGFILTERANY;Alle filer +ICMPANEL_FILEDLGFILTERICM;ICC profilfiler +ICMPANEL_GAMMABEFOREINPUT;Profilen tilføyer Gamma +ICMPANEL_INPUTCAMERA;Kameravalg +ICMPANEL_INPUTCUSTOM;Egen +ICMPANEL_INPUTDLGLABEL;Velg inngangs ICC-profil... +ICMPANEL_INPUTEMBEDDED;Anvend intern, hvis mulig +ICMPANEL_INPUTPROFILE;Inngangprofil +ICMPANEL_NOICM;Ingen ICM: sRGB-profil +ICMPANEL_OUTPUTDLGLABEL;Velg utgangs ICC-profil... +ICMPANEL_OUTPUTPROFILE;Utgangsprofil +ICMPANEL_SAVEREFERENCE;Lagre referansebilde til profil +ICMPANEL_WORKINGPROFILE;Arbeidsprofil +IMAGEAREA_DETAILVIEW;Detaljert +IPTCPANEL_AUTHORHINT;Navnet på oppretteren, f.eks. forfatter, fotograf eller grafiker (By-line). +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_EXIT;Exit +MAIN_BUTTON_PREFERENCES;Innstillinger +MAIN_BUTTON_QUEUE;Put to queue +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_EXITJOBSINQUEUEINFO;Uprosesserte bilder i køen vil bli tapt ved avslutning. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Vil du avslutte? Det er uprosesserte bilder i køen. +MAIN_MSG_JOBSINQUEUE;Arbeidet settes i kø +MAIN_MSG_QOVERWRITE;Vil du overskrive? +MAIN_TAB_BASIC;Grunnleggende +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_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;Endre +MAIN_TOOLTIP_HIDEFP;Vis/skjul nederste panel (Mapper og Filgjennomsyn, shortcut key: F) +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_PREFERENCES;Endre innstillinger +MAIN_TOOLTIP_QINFO;Hurtig informasjon om bildet +MAIN_TOOLTIP_SAVEAS;Lagre bildet i en annen mappe +MAIN_TOOLTIP_SAVE;Lagre bildet i standardmappen +PARTIALPASTE_BASICGROUP;Basisinnstillinger +PARTIALPASTE_CACORRECTION;C/A korreksjon +PARTIALPASTE_COARSETRANS;90° rotasjon/flipping +PARTIALPASTE_COLORBOOST;Fargeforsterkning +PARTIALPASTE_COLORDENOISE;Fargestøyreduksjon +PARTIALPASTE_COLORGROUP;Fargerelaterte innstillinger +PARTIALPASTE_COLORMIXER;Farge mikser +PARTIALPASTE_COLORSHIFT;Fargeskift +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_HLRECOVERY;Highlight recovery +PARTIALPASTE_ICMSETTINGS;ICM settings +PARTIALPASTE_IPTCINFO;IPTC info +PARTIALPASTE_LENSGROUP;Objektivrelaterte innstillinger +PARTIALPASTE_LUMACURVE;Luminanskurve +PARTIALPASTE_LUMADENOISE;Luminansstøyreduksjon +PARTIALPASTE_LUMINANCEGROUP;Luminansrelaterte innstillinger +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_CACHESTRAT1;Prioriter hastighet fremfor lavt minneforbruk +PREFERENCES_CACHESTRAT2;Prioriter lavt minneforbruk fremfor hastighet +PREFERENCES_CACHESTRAT;Cache strategi +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_DEMOSAICINGALGO;Demosaikking Algoritme +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_HINT;Tips +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_LIVETHUMBNAILS;Live Thumbnails (tregere) +PREFERENCES_MONITORICC;Skjermprofil +PREFERENCES_OUTDIRFOLDERHINT;Send lagrede bilder til valgt folder +PREFERENCES_OUTDIRFOLDER;Lagre til folder +PREFERENCES_OUTDIRHINT;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\nHvis 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_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_SELECTICCDIRDLG;Velg ICC-profil mappe... +PREFERENCES_SELECTLANG;Velg språk +PREFERENCES_SELECTMONITORPROFDLG;Velg ICC-profil til skjermen... +PREFERENCES_SELECTTHEME;Velg tema +PREFERENCES_SHOWBASICEXIF;Vis utvidet Exif-informasjon +PREFERENCES_SHOWDATETIME;Vis dato og tid +PREFERENCES_SHOWONLYRAW;Vis kun RAW-filer +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 +PREFERENCES_TAB_OUTPUT;Utfilindtillinger +PREFERENCES_THUMBSIZE;Miniatyrebildestørrelse +PROFILEPANEL_FILEDLGFILTERANY;Alle filer +PROFILEPANEL_FILEDLGFILTERPP;Bildebehandlingsprofiler +PROFILEPANEL_LABEL;Bildebehandlingsprofiler +PROFILEPANEL_LOADDLGLABEL;Åpne bildebehandlingsparametre... +PROFILEPANEL_PCUSTOM;Egen +PROFILEPANEL_PFILE;Fra fil +PROFILEPANEL_PLASTPHOTO;Seneste foto +PROFILEPANEL_PLASTSAVED;Seneste lagret +PROFILEPANEL_PROFILE;Profil +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_DECODING;Dekod Raw-fil... +PROGRESSBAR_DEMOSAICING;Demosaikker... +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_FOCALLENGTH;Brennvidde +QINFO_ISO;ISO +QINFO_LENS;Objektiv +QINFO_NOEXIF;Exifdata utilgjengelig. +SAVEDLG_FILEFORMAT;Filformat +SAVEDLG_JPEGQUAL;JPEG-kvalitet +SAVEDLG_JPGFILTER;JPEG-filter +SAVEDLG_PNGCOMPR;PNG-komprimering +SAVEDLG_PNGFILTER;PNG-filter +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_OUTPUTDLGLABEL;Select Velg utgangs ICC-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_LUMADENOISE_EDGETOLERANCE;Kanttoleranse +TP_LUMADENOISE_LABEL;Luminans-støyredusering +TP_LUMADENOISE_RADIUS;Radius +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_FULLSIZE;Bildestørrelse: +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 +ZOOMBAR_DETAIL;Lupe +ZOOMBAR_HUGE;Ekstra stor +ZOOMBAR_LARGE;Stor +ZOOMBAR_NORMAL;Normal +ZOOMBAR_PREVIEW;Filgjennomsyn +ZOOMBAR_SCALE;Skala +ZOOMBAR_SMALL;Liten + +#00 Norwegian +#01 2009-02-12 +#02 Translated by Esben L. Kristensen + +!!!!!!!!!!!!!!!!!!!!!!!!! +! 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 +!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_SHARPENEDGE;Bypass Edge Sharpening +!EXPORT_BYPASS_SHARPENING;Bypass Sharpening +!EXPORT_BYPASS_SHARPENMICRO;Bypass Microcontrast +!EXPORT_BYPASS_SH_HQ;Bypass Shadow/Highlights (High Quality) +!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 the path text box.\nEnter / Ctrl-Enter (in the File Browser) to browse there;\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_CURRENT_NAME;Current name: +!FILEBROWSER_DARKFRAME;Dark frame +!FILEBROWSER_DELETEDLGMSGINCLPROC;Are you sure you want to delete the selected %1 files including a queue-processed version? +!FILEBROWSER_EXEC_CPB;Custom Profile Builder +!FILEBROWSER_EXTPROGMENU;Open with +!FILEBROWSER_FLATFIELD;Flat Field +!FILEBROWSER_MOVETODARKFDIR;Move to dark frames directory +!FILEBROWSER_MOVETOFLATFIELDDIR;Move to flat fields directory +!FILEBROWSER_NEW_NAME;New name: +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!FILEBROWSER_POPUPCOLORLABEL0;Label: None +!FILEBROWSER_POPUPCOLORLABEL1;Label: Red +!FILEBROWSER_POPUPCOLORLABEL2;Label: Yellow +!FILEBROWSER_POPUPCOLORLABEL3;Label: Green +!FILEBROWSER_POPUPCOLORLABEL4;Label: Blue +!FILEBROWSER_POPUPCOLORLABEL5;Label: Purple +!FILEBROWSER_POPUPCOLORLABEL;Color label +!FILEBROWSER_POPUPCOPYTO;Copy to... +!FILEBROWSER_POPUPFILEOPERATIONS;File Operations +!FILEBROWSER_POPUPMOVETO;Move to... +!FILEBROWSER_POPUPPROCESSFAST;Put to Queue (Fast export) +!FILEBROWSER_POPUPPROFILEOPERATIONS;Processing Profile Operations +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_POPUPREMOVESUBMENU;Remove +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!FILEBROWSER_QUERYHINT;Type a partial filename to search for.\nCtrl-F to focus the Find text box (in the File Browser).\nEnter to commence search. +!FILEBROWSER_QUERYLABEL; Find: +!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 +!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-` +!FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +!FILEBROWSER_USETEMPLATE;Use template: +!GENERAL_AFTER;After +!GENERAL_BEFORE;Before +!GENERAL_FILE;File +!GENERAL_HIGH_QUALITY;High Quality +!GENERAL_NONE;None +!GENERAL_UNCHANGED;(Unchanged) +!GENERAL_WARNING;Warning +!HISTOGRAM_BUTTON_BAR;RGB +!HISTOGRAM_BUTTON_B;B +!HISTOGRAM_BUTTON_G;G +!HISTOGRAM_BUTTON_L;L +!HISTOGRAM_BUTTON_RAW;Raw +!HISTOGRAM_BUTTON_R;R +!HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar\nClick right mouse button on image preview to freeze/unfreeze +!HISTOGRAM_TOOLTIP_FULL;Toggle full or scaled histogram +!HISTOGRAM_TOOLTIP_RAW;Show/Hide raw histogram +!HISTORY_MSG_82;Profile Changed +!HISTORY_MSG_83;High Quality Shadows/Highlights +!HISTORY_MSG_84;Perspective Correction +!HISTORY_MSG_85;Lens Correction Profile +!HISTORY_MSG_86;Wavelet Equalizer +!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 +!HISTORY_MSG_92;NR - Gamma +!HISTORY_MSG_93;Contrast by Detail Levels Value +!HISTORY_MSG_94;Contrast by Detail Levels +!HISTORY_MSG_95;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;RGB Saturation +!HISTORY_MSG_101;HSV EQ -- Hue +!HISTORY_MSG_102;HSV EQ -- Saturation +!HISTORY_MSG_103;HSV EQ -- Value +!HISTORY_MSG_104;HSV Equalizer +!HISTORY_MSG_105;Defringing +!HISTORY_MSG_106;Defringing Radius +!HISTORY_MSG_107;Defringing Threshold +!HISTORY_MSG_108;Highlight Compr. Threshold +!HISTORY_MSG_109;Resize Bounding Box +!HISTORY_MSG_110;Resizing applies o +!HISTORY_MSG_111;Avoid Color Shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;Red and Skin Tones Protection +!HISTORY_MSG_114;DCB Iterations +!HISTORY_MSG_115;False Color Iterations +!HISTORY_MSG_116;Enhanced DCB +!HISTORY_MSG_117;Red CA Correction +!HISTORY_MSG_118;Blue CA Correction +!HISTORY_MSG_119;Line Denoise +!HISTORY_MSG_120;Green Equil. Threshold +!HISTORY_MSG_121;Auto CA +!HISTORY_MSG_122;Auto Dark Frame +!HISTORY_MSG_123;Dark Frame File +!HISTORY_MSG_124;Linear Exp. Correction +!HISTORY_MSG_125;Exp. Correction Preserving HL +!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;Gamma +!HISTORY_MSG_134;Gamma Position +!HISTORY_MSG_135;Gamma Free +!HISTORY_MSG_136;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 Green Together +!HISTORY_MSG_142;Edges Sharpening - Iterations +!HISTORY_MSG_143;Edges Sharpening - Quantity +!HISTORY_MSG_144;Microcontrast - Quantity +!HISTORY_MSG_145;Microcontrast - Uniformity +!HISTORY_MSG_146;Edges Sharpening +!HISTORY_MSG_147;Edges Sharpening - 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;Vibrance - Pastel tones +!HISTORY_MSG_153;Vibrance - Saturated tones +!HISTORY_MSG_154;Vibrance - Protect skin tones +!HISTORY_MSG_155;Vibrance - Avoid color drift +!HISTORY_MSG_156;Vibrance - Link pastel and saturated tones +!HISTORY_MSG_157;Vibrance - Pastel/Saturated threshold +!HISTORY_MSG_158;Strength +!HISTORY_MSG_159;Edge Stopping +!HISTORY_MSG_160;Scale +!HISTORY_MSG_161;Reweighting Iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_163;RGB Curves - R +!HISTORY_MSG_164;RGB Curves - G +!HISTORY_MSG_165;RGB Curves - B +!HISTORY_MSG_166;Neutral Levels +!HISTORY_MSG_167;B&W Toning +!HISTORY_MSG_168;'Cc' curve +!HISTORY_MSG_169;'Ch' curve +!HISTORY_MSG_170;Vibrance - Curve +!MAIN_BUTTON_FULLSCREEN;Fullscreen +!MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Put current image to processing queue.\nShortcut: Ctrl+Q +!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_ERRORDURINGIMAGESAVING;Error during image saving +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue processed first. +!MAIN_MSG_NAVIGATOR;Navigator +!MAIN_MSG_PLACES;Places +!MAIN_TAB_COLOR_TOOLTIP;Shortcut: Alt-C +!MAIN_TAB_DETAIL_TOOLTIP;Shortcut: Alt-D +!MAIN_TAB_EXPORT; 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_TOGGLE_BEFORE_AFTER;B|A +!MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 8 +!MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 0 +!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_CHANNELMIXER;Channel mixer +!PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto fill +!PARTIALPASTE_DARKFRAMEAUTOSELECT;Dark Frame Auto Select +!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;FF Auto Select +!PARTIALPASTE_FLATFIELDBLURRADIUS;FF Blur Radius +!PARTIALPASTE_FLATFIELDBLURTYPE;FF Blur Type +!PARTIALPASTE_FLATFIELDFILE;Flat field (FF) File +!PARTIALPASTE_HLRECONSTRUCTION;Highlight reconstruction +!PARTIALPASTE_HLRECOVERYAMOUNT;Highlight recovery amount +!PARTIALPASTE_HLRECOVERYTHRESHOLD;Highlight recovery threshold +!PARTIALPASTE_HSVEQUALIZER;HSV Equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!PARTIALPASTE_LABCURVE;Lab adjustments +!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 Level +!PARTIALPASTE_RAWEXPOS_LINEAR;Raw white point linear corr. factor +!PARTIALPASTE_RAWEXPOS_PRESER;Raw white point HL preserving corr. (EV) +!PARTIALPASTE_RAWGROUP;Raw settings +!PARTIALPASTE_RAW_ALLENHANCE;Apply post demosaic artifact/noise reduction +!PARTIALPASTE_RAW_DCBENHANCE;Apply DCB enhancement step +!PARTIALPASTE_RAW_DCBITERATIONS;Number of DCB iterations +!PARTIALPASTE_RAW_DMETHOD;Demosaic Method +!PARTIALPASTE_RAW_FALSECOLOR;Demosaic False color suppression steps +!PARTIALPASTE_RGBCURVES;RGB curves +!PARTIALPASTE_SHARPENEDGE;Edges +!PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_VIBRANCE;Vibrance +!PARTIALPASTE_WAVELETEQUALIZER;Wavelet equalizer +!PREFERENCES_ADD;ADD +!PREFERENCES_AUTOMONPROFILE;Automatically use operating system's main monitor color profile +!PREFERENCES_BATCH_PROCESSING;Batch Processing +!PREFERENCES_BEHAVIOR;Behavior +!PREFERENCES_CUSTPROFBUILDHINT;Executable (or script) file called when a new initial processing profile should be generated for an image.\nReceives command line parameters to allow a rules-based processing profile generation:\n[raw/JPG path] [default processing profile path] [f-number] [exposure in secs] [focal length in mm] [ISO] [lens] [camera] +!PREFERENCES_CUSTPROFBUILDPATH;Executable path +!PREFERENCES_CUSTPROFBUILD;Custom Processing Profile Builder +!PREFERENCES_CUTOVERLAYBRUSH;Crop mask color/transparency +!PREFERENCES_DARKFRAMEFOUND;Found +!PREFERENCES_DARKFRAMESHOTS;shots +!PREFERENCES_DARKFRAMETEMPLATES;templates +!PREFERENCES_DARKFRAME;Dark Frame +!PREFERENCES_DATEFORMATFRAME;Date Format +!PREFERENCES_DIRDARKFRAMES;Dark frames directory +!PREFERENCES_EDITORLAYOUT;Editor Layout +!PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar (de-select for low res display) +!PREFERENCES_FLATFIELDFOUND;Found +!PREFERENCES_FLATFIELDSDIR;Flat Fields directory +!PREFERENCES_FLATFIELDSHOTS;shots +!PREFERENCES_FLATFIELDTEMPLATES;templates +!PREFERENCES_FLATFIELD;Flat Field +!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_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). On Windows use "SystemDefault", "SystemAsterisk" etc. for system sounds. +!PREFERENCES_SND_LNGEDITPROCDONE;Editor processing done +!PREFERENCES_SND_TRESHOLDSECS;after secs +!PREFERENCES_SQUAREDETAILWINDOW;Square detail window (faster) +!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_USESYSTEMTHEME; Use system theme +!PREFERENCES_WORKFLOW;Layout +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_SAVEPPASTE;Parameters to save +!PROGRESSBAR_BADPIXELS;Bad pixels... +!PROGRESSBAR_CACORRECTION;CA correction... +!PROGRESSBAR_DARKFRAME;Darkframe... +!PROGRESSBAR_GREENEQUIL;Green equilibrate... +!PROGRESSBAR_LINEDENOISE;Line Denoise... +!PROGRESSBAR_LOADINGTHUMBS;Loading thumbnails... +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing Profile Saved +!PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists +!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\nthe 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_CHROMATABERR_LABEL;Chromatic Aberration +!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_DETAIL_AMOUNT;Amount +!TP_DIRPYRDENOISE_CHROMA;Chrominance +!TP_DIRPYRDENOISE_GAMMA;Gamma +!TP_DIRPYRDENOISE_LABEL;Noise reduction +!TP_DIRPYRDENOISE_LUMA;Luminance +!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_EQUALIZER_CONTRAST_MINUS;Contrast- +!TP_EQUALIZER_CONTRAST_PLUS;Contrast+ +!TP_EQUALIZER_FINEST;finest +!TP_EQUALIZER_LABEL;Wavelet equalizer +!TP_EQUALIZER_LARGEST;coarsest +!TP_EQUALIZER_NEUTRAL;Neutral +!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 +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in auto levels operation +!TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Highlight recovery threshold +!TP_EXPOSURE_SATURATION;Saturation +!TP_EXPO_AFTER; After interpolation (before RGB conversion) +!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_HLREC_BLEND;Blend +!TP_HSVEQUALIZER_CHANNEL;HSV Channel +!TP_HSVEQUALIZER_HUE;H +!TP_HSVEQUALIZER_LABEL;HSV Equalizer +!TP_HSVEQUALIZER_NEUTRAL;Neutral +!TP_HSVEQUALIZER_SAT;S +!TP_HSVEQUALIZER_VAL;V +!TP_ICM_BLENDCMSMATRIX;Blend highlights with matrix +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover blown highlights when using LUT based ICC profiles +!TP_ICM_INPUTCAMERAICC;Auto-matched camera-specific color profile +!TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profile. These profiles are more precise than simpler matrix ones. Available for some 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_PREFERREDPROFILE;Preferred DCP profile +!TP_ICM_PREFERREDPROFILE_1;Daylight +!TP_ICM_PREFERREDPROFILE_2;Tungsten +!TP_ICM_PREFERREDPROFILE_3;Fluorescent +!TP_ICM_PREFERREDPROFILE_4;Flash +!TP_IMPULSEDENOISE_LABEL;Impulse Noise Reduction +!TP_IMPULSEDENOISE_THRESH;Impulse NR Threshold +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid Color Shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space\nand apply Munsell correction +!TP_LABCURVE_BRIGHTNESS;Brightness +!TP_LABCURVE_BWTONING;B&W Toning +!TP_LABCURVE_BWTONING_TIP;With B&W Toning option enabled, the Lab Chromaticity, Cc and Ch curves are not in effect.\nToning can be achieved using the a and b curves +!TP_LABCURVE_CHROMATICITY;Chromaticity +!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 the Chromaticity +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to the Hue +!TP_LABCURVE_LABEL;Lab Adjustments +!TP_LABCURVE_RSTPROTECTION;Red and Skin Tones Protection +!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;Use CA correction +!TP_LENSPROFILE_USEDIST;Use distortion correction +!TP_LENSPROFILE_USEVIGN;Use vignette correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset exposure controls to neutral values +!TP_PERSPECTIVE_HORIZONTAL;Horizontal +!TP_PERSPECTIVE_LABEL;Perspective +!TP_PERSPECTIVE_VERTICAL;Vertical +!TP_PREPROCESS_GREENEQUIL;Green equilibration +!TP_PREPROCESS_HOTDEADPIXFILT;Apply hot/dead pixel filter +!TP_PREPROCESS_HOTDEADPIXTHRESH;Hot/dead pixel detection threshold +!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 (leader) +!TP_RAWEXPOS_LINEAR;White Point: Linear corr. factor +!TP_RAWEXPOS_PRESER;White Point: HL preserving corr.(EV) +!TP_RAWEXPOS_TWOGREEN;Two greens together +!TP_RAW_ALLENHANCE;Apply post demosaic artifact/noise reduction +!TP_RAW_DCBENHANCE;Apply DCB enhancement step +!TP_RAW_DCBITERATIONS;Number of DCB iterations +!TP_RAW_LABEL;Demosaicing +!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_RED;R +!TP_SHARPENEDGE_AMOUNT;Quantity +!TP_SHARPENEDGE_LABEL;Edges +!TP_SHARPENEDGE_PASSES;Iterations +!TP_SHARPENEDGE_THREE;Luminance only +!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 the Hue +!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_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 +!ZOOMPANEL_100;(100%) +!ZOOMPANEL_NEWCROPWINDOW;Open (new) detail window +!ZOOMPANEL_ZOOM100;Zoom to 100% 1 +!ZOOMPANEL_ZOOMFITSCREEN;Fit to screen F +!ZOOMPANEL_ZOOMIN;Zoom In + +!ZOOMPANEL_ZOOMOUT;Zoom Out - diff --git a/rtdata/languages/Polish b/rtdata/languages/Polish new file mode 100644 index 000000000..20aca2314 --- /dev/null +++ b/rtdata/languages/Polish @@ -0,0 +1,1234 @@ +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 +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_DIALOGLABEL;Filtr Exif +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_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_ARRANGEMENTHINT;Przełącza pomiędzy poziomym/pionowym wyrównaniem miniaturek +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_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_EXIFFILTERAPPLYHINT;Włącza/Wyłącza filtr Exif w przeglądarce plików +FILEBROWSER_EXIFFILTERAPPLY;Zastosuj +FILEBROWSER_EXIFFILTERLABEL;Filrt Exif +FILEBROWSER_EXIFFILTERSETTINGSHINT;Zmienia ustawienia filtru Exif +FILEBROWSER_EXIFFILTERSETTINGS;Ustawienia +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_POPUPCOLORLABEL0;Etykieta: Brak +FILEBROWSER_POPUPCOLORLABEL1;Etykieta: Czerwona +FILEBROWSER_POPUPCOLORLABEL2;Etykieta: Żółta +FILEBROWSER_POPUPCOLORLABEL3;Etykieta: Zielona +FILEBROWSER_POPUPCOLORLABEL4;Etykieta: Niebieska +FILEBROWSER_POPUPCOLORLABEL5;Etykieta: Purpurowa +FILEBROWSER_POPUPCOLORLABEL;Kolorowa etykieta +FILEBROWSER_POPUPCOPYTO;Skopiuj do... +FILEBROWSER_POPUPFILEOPERATIONS;Operacje na plikach +FILEBROWSER_POPUPMOVEEND;Przenieś na koniec kolejki +FILEBROWSER_POPUPMOVEHEAD;Przenieś na początek kolejki +FILEBROWSER_POPUPMOVETO;Przenieś do... +FILEBROWSER_POPUPOPEN;Otwórz +FILEBROWSER_POPUPPROCESSFAST;Dodaj do kolejki szybkiego eksportu +FILEBROWSER_POPUPPROCESS;Umieść w kolejce do przetwarzania +FILEBROWSER_POPUPPROFILEOPERATIONS;Profile +FILEBROWSER_POPUPRANK1;Ocena 1 +FILEBROWSER_POPUPRANK2;Ocena 2 +FILEBROWSER_POPUPRANK3;Ocena 3 +FILEBROWSER_POPUPRANK4;Ocena 4 +FILEBROWSER_POPUPRANK5;Ocena 5 +FILEBROWSER_POPUPREMOVEINCLPROC;Usuń z dysku i wyników przetwarzania +FILEBROWSER_POPUPREMOVESUBMENU;Usuń +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_PROCESSINGSETTINGSHINT;Ustawia format pliku i katalog wyjściowy +FILEBROWSER_PROCESSINGSETTINGS;Ustawienia +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_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_SHOWQUEUEHINT;Pokazuje zawartość kolejki przetwarzania +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-` +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_USETEMPLATE;Użyj szablonu: +FILEBROWSER_ZOOMINHINT;Zwiększa rozmiar miniaturek +FILEBROWSER_ZOOMOUTHINT;Zmniejsza rozmiar miniaturek +GENERAL_ABOUT;O programie +GENERAL_AFTER;Przed +GENERAL_BEFORE;Po +GENERAL_CANCEL;Anuluj +GENERAL_DISABLED;Wyłączone +GENERAL_DISABLE;Wyłącz +GENERAL_ENABLED;Włączone +GENERAL_ENABLE;Włącz +GENERAL_FILE;Plik +GENERAL_HIGH_QUALITY;Wysoka jakość +GENERAL_LANDSCAPE;Poziomo +GENERAL_LOAD;Ładuj +GENERAL_NA;nd. +GENERAL_NONE;Żaden +GENERAL_NO;Nie +GENERAL_OK;OK +GENERAL_PORTRAIT;Pionowo +GENERAL_SAVE;Zapisz +GENERAL_UNCHANGED;(Niezmienione) +GENERAL_YES;Tak +HISTOGRAM_BUTTON_BAR;RGB +HISTOGRAM_BUTTON_B;B +HISTOGRAM_BUTTON_G;G +HISTOGRAM_BUTTON_L;L +HISTOGRAM_BUTTON_RAW;Raw +HISTOGRAM_BUTTON_R;R +HISTOGRAM_LABEL;Histogram +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_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 -- Wartość +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_NEWSNAPSHOTAS;Jako... +HISTORY_NEWSNAPSHOT;Nowa migawka +HISTORY_NEWSSDIALOGLABEL;Nazwa migawki: +HISTORY_NEWSSDIALOGTITLE;Dodaj nową migawkę +HISTORY_SETTO;Wybrano +HISTORY_SNAPSHOTS;Migawki +HISTORY_SNAPSHOT;Migawka +ICMPANEL_FILEDLGFILTERANY;Wszystkie pliki +ICMPANEL_FILEDLGFILTERICM;Pliki z profilami ICC +ICMPANEL_GAMMABEFOREINPUT;Profil stosuje Gamma +ICMPANEL_INPUTCAMERA;Domyślny aparatu +ICMPANEL_INPUTCUSTOM;Ręczny +ICMPANEL_INPUTDLGLABEL;Wybierz wejściowy profil ICC... +ICMPANEL_INPUTEMBEDDED;Jeśli to możliwe, użyj osadzonego +ICMPANEL_INPUTPROFILE;Profil wejściowy +ICMPANEL_NOICM;No ICM: Wyjście sRGB +ICMPANEL_OUTPUTDLGLABEL;Wybierz wyjściowy profil ICC... +ICMPANEL_OUTPUTPROFILE;Profil wyjściowy +ICMPANEL_SAVEREFERENCE;Zapisz wzorcowy obraz dla profilowania +ICMPANEL_WORKINGPROFILE;Profil roboczy +IMAGEAREA_DETAILVIEW;Lupa +IPTCPANEL_AUTHORHINT;Imię lub nazwa twórcy obiektu np. pisarza, fotografa lub grafika (w linii). +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_EXIT;Wyślij do kolejki +MAIN_BUTTON_FULLSCREEN;Pełen ekran +MAIN_BUTTON_PREFERENCES;Preferencje +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Dodaj bieżące zdjęcie do kolejki przetwarzania Ctrl+Q +MAIN_BUTTON_QUEUE;Wy +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 oknie "Preferencji". +MAIN_MSG_EMPTYFILENAME;Nie podano nazwy pliku! +MAIN_MSG_ERRORDURINGIMAGESAVING;Błąd podczas zapisu zdjęcia +MAIN_MSG_EXITJOBSINQUEUEINFO;Nieprzetworzone zdjęcia w kolejce będą utracone po zamknięciu. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Na pewno zamknąć aplikację? W kolejce znajdują się nieprzetworzone zdjęcia. +MAIN_MSG_IMAGEUNPROCESSED;Ta komenda wymaga aby wszystkie wybrane zdjęcia były wpierw wywołane poprzez kolejkę. +MAIN_MSG_JOBSINQUEUE;zadań w kolejce +MAIN_MSG_NAVIGATOR;Nawigator +MAIN_MSG_PLACES;Miejsca +MAIN_MSG_QOVERWRITE;Zastąpić? +MAIN_TAB_BASIC;Podstawowe +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_ICM;ICM +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_TOGGLE_BEFORE_AFTER;Przed|Po +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_HIDEFP;Pokaż/ukryj dolny panel (przeglądarka plików i katalogów, klawisz skrótu: F) +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_PREFERENCES;Ustaw preferencje +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_SAVEAS;Zapisz obraz we wskazanym katalogu +MAIN_TOOLTIP_SAVE;Zapisz obraz w katalogu domyślnym +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_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_COLORBOOST;Uwydatnienie koloru +PARTIALPASTE_COLORDENOISE;Odszumienie koloru +PARTIALPASTE_COLORGROUP;Ustawienia związane z kolorem +PARTIALPASTE_COLORMIXER;Mikser koloru +PARTIALPASTE_COLORSHIFT;Przesunięcie koloru +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_HLRECONSTRUCTION;Odbudowa prześwietleń +PARTIALPASTE_HLRECOVERYAMOUNT;Siła odzyskiwania prześwietleń +PARTIALPASTE_HLRECOVERYTHRESHOLD;Próg odzyskiwania prześwietleń +PARTIALPASTE_HLRECOVERY;Odzyskiwanie prześwietleń +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_LUMACURVE;Krzywa obiektywu +PARTIALPASTE_LUMADENOISE;Redukcja zaszumienia jaskrawości +PARTIALPASTE_LUMINANCEGROUP;Ustawienia związane z jaskrawością +PARTIALPASTE_METAICMGROUP;Metadane/Ustawienia ICM +PARTIALPASTE_PERSPECTIVE;Perspektywa +PARTIALPASTE_PREPROCESS_GREENEQUIL;Wyrównanie zieleni +PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Zastosuj filtr gorących/martwych pikseli +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_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_WAVELETEQUALIZER;Korektor Wavelet +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_BEHAVIOR;Zachowanie +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_CACHESTRAT1;Prędkość kosztem zużycia pamięci +PREFERENCES_CACHESTRAT2;Mniejsze zużycie pamięci kosztem prędkości +PREFERENCES_CACHESTRAT;Opcje pamięci podręcznej +PREFERENCES_CACHETHUMBFORM;Format miniatur w pamięci podręcznej +PREFERENCES_CACHETHUMBHEIGHT;Maksymalna wysokość miniatury +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_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_DEMOSAICINGALGO;Algorytm demozaikowania +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_FORIMAGE;Dla zdjęć innych niż raw +PREFERENCES_FORRAW;Dla zdjęć raw +PREFERENCES_GIMPPATH;Katalog, w którym zainstalowany jest GIMP +PREFERENCES_GTKTHEME;Domyślny temat GTK +PREFERENCES_HINT;Porada +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_LIVETHUMBNAILS;Miniaturki na żywo (wolniej) +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_OUTDIRHINT;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\nAby zapisać plik wynikowy obok źródłowego, 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_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_SELECTFONT;Wybierz czcionkę +PREFERENCES_SELECTICCDIRDLG;Wybierz katalog z profilami ICC... +PREFERENCES_SELECTLANG;Wybierz język +PREFERENCES_SELECTMONITORPROFDLG;Wybierz profil ICC do wyświetlenia... +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_SHOWONLYRAW;Pokaż tylko pliki raw +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_OUTPUT;Opcje wyjściowe +PREFERENCES_TAB_SOUND;Dźwięki +PREFERENCES_THUMBSIZE;Wielkość miniaturki +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_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_PASTEPPASTE;Parametry do wklejenia +PROFILEPANEL_PCUSTOM;Ręczny +PROFILEPANEL_PFILE;Z pliku +PROFILEPANEL_PLASTPHOTO;Ostatnie zdjęcie +PROFILEPANEL_PLASTSAVED;Ostatnio zapisany +PROFILEPANEL_PROFILE;Profil +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_BADPIXELS;Uszkodzone piksele... +PROGRESSBAR_CACORRECTION;Korekacja aberracji chromatycznej... +PROGRESSBAR_DARKFRAME;Czarna klatka... +PROGRESSBAR_DECODING;Dekodowanie pliku raw... +PROGRESSBAR_DEMOSAICING;Demozaikowanie... +PROGRESSBAR_GREENEQUIL;Wyrównywanie zieleni... +PROGRESSBAR_LINEDENOISE;Liniowa redukcja szumu... +PROGRESSBAR_LOADINGTHUMBS;Wczytywanie miniatur... +PROGRESSBAR_LOADING;Wczytywanie obrazu... +PROGRESSBAR_LOADJPEG;Ładowanie pliku JPEG... +PROGRESSBAR_LOADPNG;Ładowanie pliku PNG... +PROGRESSBAR_LOADTIFF;Ładowanie pliku TIFF... +PROGRESSBAR_PROCESSING;Przetwarzanie obrazu... +PROGRESSBAR_READY;Gotowe. +PROGRESSBAR_SAVEJPEG;Zapisywanie pliku JPEG... +PROGRESSBAR_SAVEPNG;Zapisywanie pliku PNG... +PROGRESSBAR_SAVETIFF;Zapisywanie pliku TIFF... +PROGRESSDLG_LOADING;Wczytywanie pliku... +PROGRESSDLG_PROCESSING;Przetwarzanie zdjęcia... +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profil zmieniony w przeglądarce +PROGRESSDLG_SAVING;Zapisywanie pliku... +QINFO_FOCALLENGTH;Ogniskowa +QINFO_ISO;ISO +QINFO_LENS;Obiektyw +QINFO_NOEXIF;Dane exif niedostępne. +SAVEDLG_AUTOSUFFIX;Automatycznie dodaj przyrostek, jeżeli plik już istnieje +SAVEDLG_FILEFORMAT;Format pliku +SAVEDLG_JPEGQUAL;Jakość JPEG +SAVEDLG_JPGFILTER;Pliki JPEG +SAVEDLG_PNGCOMPR;Kompresja PNG +SAVEDLG_PNGFILTER;Pliki 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_TIFFFILTER;Pliki TIFF +SAVEDLG_TIFFUNCOMPRESSED;Nieskompresowany TIFF +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_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_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_CHROMA;Chrominacja +TP_DIRPYRDENOISE_GAMMA;Gamma +TP_DIRPYRDENOISE_LABEL;Redukcja szumu +TP_DIRPYRDENOISE_LUMA;Luminacja +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_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_CURVEEDITOR;Krzywa tonalna +TP_EXPOSURE_EXPCOMP;EV +TP_EXPOSURE_LABEL;Ekspozycja +TP_EXPOSURE_SATURATION;Nasycenie +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_NEUTRAL;Neutralne +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 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 kolorów 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_OUTPUTDLGLABEL;Wybierz wyjściowy profil ICC... +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_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_BRIGHTNESS;Jasność +TP_LABCURVE_CONTRAST;Kontrast +TP_LABCURVE_CURVEEDITOR;Krzywa luminacji +TP_LABCURVE_ENABLESATLIMITER;Limitowanie nasycenia +TP_LABCURVE_LABEL;Regulacja Lab +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_LUMADENOISE_EDGETOLERANCE;Tolerancja krawędzi +TP_LUMADENOISE_LABEL;Odszumianie luminancji +TP_LUMADENOISE_RADIUS;Promień +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_PREPROCESS_GREENEQUIL;Wyrównanie zieleni +TP_PREPROCESS_HOTDEADPIXFILT;Użyj filtra gorących/martwych pikseli +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_FALSECOLOR;Kroki zapobiegające fałszowaniu kolorów +TP_RAW_LABEL;Demozaikowanie +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_FULLSIZE;Pełny rozmiar obrazu: +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_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_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_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_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 +ZOOMBAR_DETAIL;Lupa +ZOOMBAR_HUGE;Olbrzymia +ZOOMBAR_LARGE;Duża +ZOOMBAR_NORMAL;Normalna +ZOOMBAR_PREVIEW;Widok +ZOOMBAR_SCALE;Skala +ZOOMBAR_SMALL;Mała +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;Otwórz (nową) lupę +ZOOMPANEL_ZOOM100;Powiększ do 100% 1 +ZOOMPANEL_ZOOMFITSCREEN;Dopasuj do ekranu F +ZOOMPANEL_ZOOMIN;Przybliż + +ZOOMPANEL_ZOOMOUT;Oddal - + +#00 Polish +#01 24.12.2007 +#02 Mateusz Ludwin +#03 ----------------------------- +#04 08.01.2010 +#05 Initial update for 3.0 release +#06 Bartosz "Simek" Kaszubowski +#07 ----------------------------- +#08 06.09.2011 +#09 Dariusz 'Salvadhor' Duma +#10 The race for the bleeding edge - update for 4.x +#11 2011-11-30 DrSlony +#12 2012-01-14 DrSlony +#13 2012-01-30 DrSlony +#13 2012-04-02 DrSlony + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!GENERAL_WARNING;Warning +!HISTOGRAM_TOOLTIP_FULL;Toggle full or scaled histogram +!HISTORY_MSG_167;B&W Toning +!HISTORY_MSG_168;'Cc' curve +!HISTORY_MSG_169;'Ch' curve +!HISTORY_MSG_170;Vibrance - Curve +!MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 8 +!MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 0 +!NAVIGATOR_XY_FULL;Width = %1, Height = %2 +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing Profile Saved +!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\nthe 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_CROP_GTFRAME;Frame +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid Color Shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space\nand apply Munsell correction +!TP_LABCURVE_BWTONING;B&W Toning +!TP_LABCURVE_BWTONING_TIP;With B&W Toning option enabled, the Lab Chromaticity, Cc and Ch curves are not in effect.\nToning can be achieved using the a and b curves +!TP_LABCURVE_CHROMATICITY;Chromaticity +!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 the Chromaticity +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to the Hue +!TP_LABCURVE_RSTPROTECTION;Red and Skin Tones Protection +!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 the Hue +!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 diff --git a/rtdata/languages/Polish (Latin Characters) b/rtdata/languages/Polish (Latin Characters) new file mode 100644 index 000000000..29c91ce3c --- /dev/null +++ b/rtdata/languages/Polish (Latin Characters) @@ -0,0 +1,1234 @@ +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 +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_DIALOGLABEL;Filtr Exif +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_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_ARRANGEMENTHINT;Przelacza pomiedzy poziomym/pionowym wyrownaniem miniaturek +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_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_EXIFFILTERAPPLYHINT;Wlacza/Wylacza filtr Exif w przegladarce plikow +FILEBROWSER_EXIFFILTERAPPLY;Zastosuj +FILEBROWSER_EXIFFILTERLABEL;Filrt Exif +FILEBROWSER_EXIFFILTERSETTINGSHINT;Zmienia ustawienia filtru Exif +FILEBROWSER_EXIFFILTERSETTINGS;Ustawienia +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_POPUPCOLORLABEL0;Etykieta: Brak +FILEBROWSER_POPUPCOLORLABEL1;Etykieta: Czerwona +FILEBROWSER_POPUPCOLORLABEL2;Etykieta: Zolta +FILEBROWSER_POPUPCOLORLABEL3;Etykieta: Zielona +FILEBROWSER_POPUPCOLORLABEL4;Etykieta: Niebieska +FILEBROWSER_POPUPCOLORLABEL5;Etykieta: Purpurowa +FILEBROWSER_POPUPCOLORLABEL;Kolorowa etykieta +FILEBROWSER_POPUPCOPYTO;Skopiuj do... +FILEBROWSER_POPUPFILEOPERATIONS;Operacje na plikach +FILEBROWSER_POPUPMOVEEND;Przenies na koniec kolejki +FILEBROWSER_POPUPMOVEHEAD;Przenies na poczatek kolejki +FILEBROWSER_POPUPMOVETO;Przenies do... +FILEBROWSER_POPUPOPEN;Otworz +FILEBROWSER_POPUPPROCESSFAST;Dodaj do kolejki szybkiego eksportu +FILEBROWSER_POPUPPROCESS;Umiesc w kolejce do przetwarzania +FILEBROWSER_POPUPPROFILEOPERATIONS;Profile +FILEBROWSER_POPUPRANK1;Ocena 1 +FILEBROWSER_POPUPRANK2;Ocena 2 +FILEBROWSER_POPUPRANK3;Ocena 3 +FILEBROWSER_POPUPRANK4;Ocena 4 +FILEBROWSER_POPUPRANK5;Ocena 5 +FILEBROWSER_POPUPREMOVEINCLPROC;Usun z dysku i wynikow przetwarzania +FILEBROWSER_POPUPREMOVESUBMENU;Usun +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_PROCESSINGSETTINGSHINT;Ustawia format pliku i katalog wyjsciowy +FILEBROWSER_PROCESSINGSETTINGS;Ustawienia +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_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_SHOWQUEUEHINT;Pokazuje zawartosc kolejki przetwarzania +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-` +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_USETEMPLATE;Uzyj szablonu: +FILEBROWSER_ZOOMINHINT;Zwieksza rozmiar miniaturek +FILEBROWSER_ZOOMOUTHINT;Zmniejsza rozmiar miniaturek +GENERAL_ABOUT;O programie +GENERAL_AFTER;Przed +GENERAL_BEFORE;Po +GENERAL_CANCEL;Anuluj +GENERAL_DISABLED;Wylaczone +GENERAL_DISABLE;Wylacz +GENERAL_ENABLED;Wlaczone +GENERAL_ENABLE;Wlacz +GENERAL_FILE;Plik +GENERAL_HIGH_QUALITY;Wysoka jakosc +GENERAL_LANDSCAPE;Poziomo +GENERAL_LOAD;Laduj +GENERAL_NA;nd. +GENERAL_NONE;Zaden +GENERAL_NO;Nie +GENERAL_OK;OK +GENERAL_PORTRAIT;Pionowo +GENERAL_SAVE;Zapisz +GENERAL_UNCHANGED;(Niezmienione) +GENERAL_YES;Tak +HISTOGRAM_BUTTON_BAR;RGB +HISTOGRAM_BUTTON_B;B +HISTOGRAM_BUTTON_G;G +HISTOGRAM_BUTTON_L;L +HISTOGRAM_BUTTON_RAW;Raw +HISTOGRAM_BUTTON_R;R +HISTOGRAM_LABEL;Histogram +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_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 -- Wartosc +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_NEWSNAPSHOTAS;Jako... +HISTORY_NEWSNAPSHOT;Nowa migawka +HISTORY_NEWSSDIALOGLABEL;Nazwa migawki: +HISTORY_NEWSSDIALOGTITLE;Dodaj nowa migawke +HISTORY_SETTO;Wybrano +HISTORY_SNAPSHOTS;Migawki +HISTORY_SNAPSHOT;Migawka +ICMPANEL_FILEDLGFILTERANY;Wszystkie pliki +ICMPANEL_FILEDLGFILTERICM;Pliki z profilami ICC +ICMPANEL_GAMMABEFOREINPUT;Profil stosuje Gamma +ICMPANEL_INPUTCAMERA;Domyslny aparatu +ICMPANEL_INPUTCUSTOM;Reczny +ICMPANEL_INPUTDLGLABEL;Wybierz wejsciowy profil ICC... +ICMPANEL_INPUTEMBEDDED;Jesli to mozliwe, uzyj osadzonego +ICMPANEL_INPUTPROFILE;Profil wejsciowy +ICMPANEL_NOICM;No ICM: Wyjscie sRGB +ICMPANEL_OUTPUTDLGLABEL;Wybierz wyjsciowy profil ICC... +ICMPANEL_OUTPUTPROFILE;Profil wyjsciowy +ICMPANEL_SAVEREFERENCE;Zapisz wzorcowy obraz dla profilowania +ICMPANEL_WORKINGPROFILE;Profil roboczy +IMAGEAREA_DETAILVIEW;Lupa +IPTCPANEL_AUTHORHINT;Imie lub nazwa tworcy obiektu np. pisarza, fotografa lub grafika (w linii). +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_EXIT;Wyslij do kolejki +MAIN_BUTTON_FULLSCREEN;Pelen ekran +MAIN_BUTTON_PREFERENCES;Preferencje +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Dodaj biezace zdjecie do kolejki przetwarzania Ctrl+Q +MAIN_BUTTON_QUEUE;Wy +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 oknie "Preferencji". +MAIN_MSG_EMPTYFILENAME;Nie podano nazwy pliku! +MAIN_MSG_ERRORDURINGIMAGESAVING;Blad podczas zapisu zdjecia +MAIN_MSG_EXITJOBSINQUEUEINFO;Nieprzetworzone zdjecia w kolejce beda utracone po zamknieciu. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Na pewno zamknac aplikacje? W kolejce znajduja sie nieprzetworzone zdjecia. +MAIN_MSG_IMAGEUNPROCESSED;Ta komenda wymaga aby wszystkie wybrane zdjecia byly wpierw wywolane poprzez kolejke. +MAIN_MSG_JOBSINQUEUE;zadan w kolejce +MAIN_MSG_NAVIGATOR;Nawigator +MAIN_MSG_PLACES;Miejsca +MAIN_MSG_QOVERWRITE;Zastapic? +MAIN_TAB_BASIC;Podstawowe +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_ICM;ICM +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_TOGGLE_BEFORE_AFTER;Przed|Po +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_HIDEFP;Pokaz/ukryj dolny panel (przegladarka plikow i katalogow, klawisz skrotu: F) +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_PREFERENCES;Ustaw preferencje +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_SAVEAS;Zapisz obraz we wskazanym katalogu +MAIN_TOOLTIP_SAVE;Zapisz obraz w katalogu domyslnym +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_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_COLORBOOST;Uwydatnienie koloru +PARTIALPASTE_COLORDENOISE;Odszumienie koloru +PARTIALPASTE_COLORGROUP;Ustawienia zwiazane z kolorem +PARTIALPASTE_COLORMIXER;Mikser koloru +PARTIALPASTE_COLORSHIFT;Przesuniecie koloru +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_HLRECONSTRUCTION;Odbudowa przeswietlen +PARTIALPASTE_HLRECOVERYAMOUNT;Sila odzyskiwania przeswietlen +PARTIALPASTE_HLRECOVERYTHRESHOLD;Prog odzyskiwania przeswietlen +PARTIALPASTE_HLRECOVERY;Odzyskiwanie przeswietlen +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_LUMACURVE;Krzywa obiektywu +PARTIALPASTE_LUMADENOISE;Redukcja zaszumienia jaskrawosci +PARTIALPASTE_LUMINANCEGROUP;Ustawienia zwiazane z jaskrawoscia +PARTIALPASTE_METAICMGROUP;Metadane/Ustawienia ICM +PARTIALPASTE_PERSPECTIVE;Perspektywa +PARTIALPASTE_PREPROCESS_GREENEQUIL;Wyrownanie zieleni +PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Zastosuj filtr goracych/martwych pikseli +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_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_WAVELETEQUALIZER;Korektor Wavelet +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_BEHAVIOR;Zachowanie +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_CACHESTRAT1;Predkosc kosztem zuzycia pamieci +PREFERENCES_CACHESTRAT2;Mniejsze zuzycie pamieci kosztem predkosci +PREFERENCES_CACHESTRAT;Opcje pamieci podrecznej +PREFERENCES_CACHETHUMBFORM;Format miniatur w pamieci podrecznej +PREFERENCES_CACHETHUMBHEIGHT;Maksymalna wysokosc miniatury +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_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_DEMOSAICINGALGO;Algorytm demozaikowania +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_FORIMAGE;Dla zdjec innych niz raw +PREFERENCES_FORRAW;Dla zdjec raw +PREFERENCES_GIMPPATH;Katalog, w ktorym zainstalowany jest GIMP +PREFERENCES_GTKTHEME;Domyslny temat GTK +PREFERENCES_HINT;Porada +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_LIVETHUMBNAILS;Miniaturki na zywo (wolniej) +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_OUTDIRHINT;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\nAby zapisac plik wynikowy obok zrodlowego, 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_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_SELECTFONT;Wybierz czcionke +PREFERENCES_SELECTICCDIRDLG;Wybierz katalog z profilami ICC... +PREFERENCES_SELECTLANG;Wybierz jezyk +PREFERENCES_SELECTMONITORPROFDLG;Wybierz profil ICC do wyswietlenia... +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_SHOWONLYRAW;Pokaz tylko pliki raw +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_OUTPUT;Opcje wyjsciowe +PREFERENCES_TAB_SOUND;Dzwieki +PREFERENCES_THUMBSIZE;Wielkosc miniaturki +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_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_PASTEPPASTE;Parametry do wklejenia +PROFILEPANEL_PCUSTOM;Reczny +PROFILEPANEL_PFILE;Z pliku +PROFILEPANEL_PLASTPHOTO;Ostatnie zdjecie +PROFILEPANEL_PLASTSAVED;Ostatnio zapisany +PROFILEPANEL_PROFILE;Profil +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_BADPIXELS;Uszkodzone piksele... +PROGRESSBAR_CACORRECTION;Korekacja aberracji chromatycznej... +PROGRESSBAR_DARKFRAME;Czarna klatka... +PROGRESSBAR_DECODING;Dekodowanie pliku raw... +PROGRESSBAR_DEMOSAICING;Demozaikowanie... +PROGRESSBAR_GREENEQUIL;Wyrownywanie zieleni... +PROGRESSBAR_LINEDENOISE;Liniowa redukcja szumu... +PROGRESSBAR_LOADINGTHUMBS;Wczytywanie miniatur... +PROGRESSBAR_LOADING;Wczytywanie obrazu... +PROGRESSBAR_LOADJPEG;Ladowanie pliku JPEG... +PROGRESSBAR_LOADPNG;Ladowanie pliku PNG... +PROGRESSBAR_LOADTIFF;Ladowanie pliku TIFF... +PROGRESSBAR_PROCESSING;Przetwarzanie obrazu... +PROGRESSBAR_READY;Gotowe. +PROGRESSBAR_SAVEJPEG;Zapisywanie pliku JPEG... +PROGRESSBAR_SAVEPNG;Zapisywanie pliku PNG... +PROGRESSBAR_SAVETIFF;Zapisywanie pliku TIFF... +PROGRESSDLG_LOADING;Wczytywanie pliku... +PROGRESSDLG_PROCESSING;Przetwarzanie zdjecia... +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profil zmieniony w przegladarce +PROGRESSDLG_SAVING;Zapisywanie pliku... +QINFO_FOCALLENGTH;Ogniskowa +QINFO_ISO;ISO +QINFO_LENS;Obiektyw +QINFO_NOEXIF;Dane exif niedostepne. +SAVEDLG_AUTOSUFFIX;Automatycznie dodaj przyrostek, jezeli plik juz istnieje +SAVEDLG_FILEFORMAT;Format pliku +SAVEDLG_JPEGQUAL;Jakosc JPEG +SAVEDLG_JPGFILTER;Pliki JPEG +SAVEDLG_PNGCOMPR;Kompresja PNG +SAVEDLG_PNGFILTER;Pliki 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_TIFFFILTER;Pliki TIFF +SAVEDLG_TIFFUNCOMPRESSED;Nieskompresowany TIFF +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_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_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_CHROMA;Chrominacja +TP_DIRPYRDENOISE_GAMMA;Gamma +TP_DIRPYRDENOISE_LABEL;Redukcja szumu +TP_DIRPYRDENOISE_LUMA;Luminacja +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_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_CURVEEDITOR;Krzywa tonalna +TP_EXPOSURE_EXPCOMP;EV +TP_EXPOSURE_LABEL;Ekspozycja +TP_EXPOSURE_SATURATION;Nasycenie +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_NEUTRAL;Neutralne +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 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 kolorow 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_OUTPUTDLGLABEL;Wybierz wyjsciowy profil ICC... +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_WORKINGPROFILE;Profil roboczy +TP_IMPULSEDENOISE_LABEL;Impulsowa redukcja szumu +TP_IMPULSEDENOISE_THRESH;Prog impulsowej redukcji szumu +TP_LABCURVE_AVOIDCOLORCLIP;Unikaj przycinania koloru +TP_LABCURVE_BRIGHTNESS;Jasnosc +TP_LABCURVE_CONTRAST;Kontrast +TP_LABCURVE_CURVEEDITOR;Krzywa luminacji +TP_LABCURVE_ENABLESATLIMITER;Limitowanie nasycenia +TP_LABCURVE_LABEL;Regulacja Lab +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_LUMADENOISE_EDGETOLERANCE;Tolerancja krawedzi +TP_LUMADENOISE_LABEL;Odszumianie luminancji +TP_LUMADENOISE_RADIUS;Promien +TP_NEUTRAL;Neutralne +TP_NEUTRAL_TIP;Zresetuj ustawienia do wartosci neutralnych +TP_PERSPECTIVE_HORIZONTAL;Pozioma +TP_PERSPECTIVE_LABEL;Perspektywa +TP_PERSPECTIVE_VERTICAL;Pionowa +TP_PREPROCESS_GREENEQUIL;Wyrownanie zieleni +TP_PREPROCESS_HOTDEADPIXFILT;Uzyj filtra goracych/martwych pikseli +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_FALSECOLOR;Kroki zapobiegajace falszowaniu kolorow +TP_RAW_LABEL;Demozaikowanie +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_FULLSIZE;Pelny rozmiar obrazu: +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_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_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_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_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 +ZOOMBAR_DETAIL;Lupa +ZOOMBAR_HUGE;Olbrzymia +ZOOMBAR_LARGE;Duza +ZOOMBAR_NORMAL;Normalna +ZOOMBAR_PREVIEW;Widok +ZOOMBAR_SCALE;Skala +ZOOMBAR_SMALL;Mala +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;Otworz (nowa) lupe +ZOOMPANEL_ZOOM100;Powieksz do 100% 1 +ZOOMPANEL_ZOOMFITSCREEN;Dopasuj do ekranu F +ZOOMPANEL_ZOOMIN;Przybliz + +ZOOMPANEL_ZOOMOUT;Oddal - + +#00 Polish +#01 24.12.2007 +#02 Mateusz Ludwin +#03 ----------------------------- +#04 08.01.2010 +#05 Initial update for 3.0 release +#06 Bartosz "Simek" Kaszubowski +#07 ----------------------------- +#08 06.09.2011 +#09 Dariusz 'Salvadhor' Duma +#10 The race for the bleeding edge - update for 4.x +#11 2011-11-30 DrSlony +#12 2012-01-14 DrSlony +#13 2012-01-30 DrSlony +#13 2012-04-02 DrSlony + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!GENERAL_WARNING;Warning +!HISTOGRAM_TOOLTIP_FULL;Toggle full or scaled histogram +!HISTORY_MSG_167;B&W Toning +!HISTORY_MSG_168;'Cc' curve +!HISTORY_MSG_169;'Ch' curve +!HISTORY_MSG_170;Vibrance - Curve +!MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 8 +!MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 0 +!NAVIGATOR_XY_FULL;Width = %1, Height = %2 +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing Profile Saved +!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\nthe 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_CROP_GTFRAME;Frame +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid Color Shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space\nand apply Munsell correction +!TP_LABCURVE_BWTONING;B&W Toning +!TP_LABCURVE_BWTONING_TIP;With B&W Toning option enabled, the Lab Chromaticity, Cc and Ch curves are not in effect.\nToning can be achieved using the a and b curves +!TP_LABCURVE_CHROMATICITY;Chromaticity +!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 the Chromaticity +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to the Hue +!TP_LABCURVE_RSTPROTECTION;Red and Skin Tones Protection +!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 the Hue +!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 diff --git a/rtdata/languages/Portugues (Brasil) b/rtdata/languages/Portugues (Brasil) new file mode 100644 index 000000000..748e8bbaa --- /dev/null +++ b/rtdata/languages/Portugues (Brasil) @@ -0,0 +1,1208 @@ +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_DIALOGLABEL;Filtro Exif +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_ARRANGEMENTHINT;Alternar entre alinhamento vertical/horizontal das miniaturas +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_EXIFFILTERAPPLYHINT; Habilitar/Desabilitar Filtro exif do navegador de arquivos +FILEBROWSER_EXIFFILTERAPPLY;Aplicar +FILEBROWSER_EXIFFILTERLABEL;Filtro Exif +FILEBROWSER_EXIFFILTERSETTINGSHINT;Alterar configurações do filtro exif +FILEBROWSER_EXIFFILTERSETTINGS;Configuração +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_POPUPRANK1;Classificação 1 +FILEBROWSER_POPUPRANK2;Classificação 2 +FILEBROWSER_POPUPRANK3;Classificação 3 +FILEBROWSER_POPUPRANK4;Classificação 4 +FILEBROWSER_POPUPRANK5;Classificação 5 +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_PROCESSINGSETTINGSHINT;Ajustar o formato de arquivo e diretório de saída +FILEBROWSER_PROCESSINGSETTINGS;Configurações +FILEBROWSER_RENAMEDLGLABEL;Renomear arquivo +FILEBROWSER_RENAMEDLGMSG;Renomear arquivo "%1" como: +FILEBROWSER_SHOWDIRHINT;Exibir todas as imagens do diretório +FILEBROWSER_SHOWQUEUEHINT;Exibir conteúdo da fila de processamento +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_LOAD;Carregar +GENERAL_NA;n/a +GENERAL_NO;Não +GENERAL_OK;OK +GENERAL_PORTRAIT;Retrato +GENERAL_SAVE;Salvar +GENERAL_YES;Sim +HISTOGRAM_LABEL;Histograma +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_NEWSNAPSHOTAS;Como... +HISTORY_NEWSNAPSHOT;Adicionar +HISTORY_NEWSSDIALOGLABEL;Etiqueta do snapshot: +HISTORY_NEWSSDIALOGTITLE;Adicionar novo snapshot +HISTORY_SETTO;Ajustar para +HISTORY_SNAPSHOTS;Snapshots +HISTORY_SNAPSHOT;Snapshot +ICMPANEL_FILEDLGFILTERANY;Quaisquer arquivos +ICMPANEL_FILEDLGFILTERICM;ICC Profile Files +ICMPANEL_GAMMABEFOREINPUT;Profile applies Gamma +ICMPANEL_INPUTCAMERA;Padrão de câmera +ICMPANEL_INPUTCUSTOM;Personalizado +ICMPANEL_INPUTDLGLABEL;selecionar perfil de entrada ICC.. +ICMPANEL_INPUTEMBEDDED;Utilizar encaixe, se possível +ICMPANEL_INPUTPROFILE;Perfil de entrada +ICMPANEL_NOICM;No ICM: Saída sRGB +ICMPANEL_OUTPUTDLGLABEL;Selecionar perfil de saída ICC... +ICMPANEL_OUTPUTPROFILE;Perfil de saída +ICMPANEL_SAVEREFERENCE;Salvar imagem de referência para perfis +ICMPANEL_WORKINGPROFILE;Prefil de atuação +IMAGEAREA_DETAILVIEW;visualisação de detalhes +IPTCPANEL_AUTHORHINT;Nome do criador do objeto, escritor, fotógrafo o artista gráfico. +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_EXIT;Exit +MAIN_BUTTON_PREFERENCES;Preferências +MAIN_BUTTON_QUEUE;Put to queue +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_EXITJOBSINQUEUEINFO;As imagens da lista que não foram processadas serão perdidas. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Tem certeza de que deseja sair? Há imagens na lista que ainda não foram processadas. +MAIN_MSG_JOBSINQUEUE;trabalho(s) na fila +MAIN_MSG_QOVERWRITE;Deseja sobreescrever? +MAIN_TAB_BASIC;Básico +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_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadados +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;Transformar +MAIN_TOOLTIP_HIDEFP;Mostrar/esconder o painel inferior (diretórios and navegador de arquivos, tecla de atalho: F) +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_PREFERENCES;Ajustar preferências +MAIN_TOOLTIP_QINFO;Informações rápidas da imagem +MAIN_TOOLTIP_SAVEAS;Salvar imagem em uma pasta selecionada +MAIN_TOOLTIP_SAVE;Salvar imagem na pasta padrão +PARTIALPASTE_BASICGROUP;Configurações básicas +PARTIALPASTE_CACORRECTION;Correção C/A +PARTIALPASTE_COARSETRANS;Rotação de 90 graus +PARTIALPASTE_COLORBOOST;Melhoria de Cor +PARTIALPASTE_COLORDENOISE;Redução de ruídos da cor +PARTIALPASTE_COLORGROUP;Configurações relacionadas à cor +PARTIALPASTE_COLORMIXER;Misturador de Cores +PARTIALPASTE_COLORSHIFT;Mudança de 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_HLRECOVERY;Recuperação de Luz +PARTIALPASTE_ICMSETTINGS;Configurações ICM +PARTIALPASTE_IPTCINFO;informações IPTC +PARTIALPASTE_LENSGROUP;Configurações relacionadas à Lente +PARTIALPASTE_LUMACURVE;Curva de luminância +PARTIALPASTE_LUMADENOISE;Redução de ruídos da luminância +PARTIALPASTE_LUMINANCEGROUP;Configurações relacionadas à 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_CACHESTRAT1;Preferir velocidade a baixo consumo de memória +PREFERENCES_CACHESTRAT2;Preferir baixo consumo de memória a velocidade +PREFERENCES_CACHESTRAT;Estratégia 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_DEMOSAICINGALGO;Algorítmo de remoção de mosaico +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_HINT;Dica +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_LIVETHUMBNAILS;Miniaturas em tempo real (mais lento) +PREFERENCES_MONITORICC;Monitorar perfil +PREFERENCES_OUTDIRFOLDERHINT;Colocar as imagens salvas na pasta selecionada +PREFERENCES_OUTDIRFOLDER;Salvar em folder +PREFERENCES_OUTDIRHINT;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_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_SELECTICCDIRDLG;Selecione o diretório de perfil ICC... +PREFERENCES_SELECTLANG;Selecionar idioma +PREFERENCES_SELECTMONITORPROFDLG;Selecione o perfil ICC da visualização... +PREFERENCES_SELECTTHEME;Selecionar tema +PREFERENCES_SHOWBASICEXIF;Mostrar informações Exif básicas +PREFERENCES_SHOWDATETIME;Mostrar data e hora +PREFERENCES_SHOWONLYRAW;Mostrar somente arquivos RAW +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 +PREFERENCES_TAB_OUTPUT;Opções de Saída +PREFERENCES_THUMBSIZE;Tamanho das Miniaturas +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_PLASTPHOTO;Ùltima Foto +PROFILEPANEL_PLASTSAVED;Último Salvo +PROFILEPANEL_PROFILE;Perfil +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_DECODING;Decodificando arquivo raw... +PROGRESSBAR_DEMOSAICING;Removendo mosaico... +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_FOCALLENGTH;Distância focal +QINFO_ISO;ISO +QINFO_LENS;Lente +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_PNGFILTER;Arquivos 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_OUTPUTDLGLABEL;Selecione perfil de saída ICC... +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_LUMADENOISE_EDGETOLERANCE;Tolerância de Bordas +TP_LUMADENOISE_LABEL;Redução de ruídos da luminância +TP_LUMADENOISE_RADIUS;Raio +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_FULLSIZE;Tamanho de Imagem Completo: +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 +ZOOMBAR_DETAIL;Detalhe +ZOOMBAR_HUGE;Muito Grande +ZOOMBAR_LARGE;Grande +ZOOMBAR_NORMAL;Normal +ZOOMBAR_PREVIEW;Pré-visualisação +ZOOMBAR_SCALE;Escala +ZOOMBAR_SMALL;Pequeno + +#00 Português Brasileiro +#01 01.02.2010: Vitor da Silva Gonçalves +# + +!!!!!!!!!!!!!!!!!!!!!!!!! +! 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 +!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_SHARPENEDGE;Bypass Edge Sharpening +!EXPORT_BYPASS_SHARPENING;Bypass Sharpening +!EXPORT_BYPASS_SHARPENMICRO;Bypass Microcontrast +!EXPORT_BYPASS_SH_HQ;Bypass Shadow/Highlights (High Quality) +!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 the path text box.\nEnter / Ctrl-Enter (in the File Browser) to browse there;\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_CURRENT_NAME;Current name: +!FILEBROWSER_DARKFRAME;Dark frame +!FILEBROWSER_DELETEDLGMSGINCLPROC;Are you sure you want to delete the selected %1 files including a queue-processed version? +!FILEBROWSER_EXEC_CPB;Custom Profile Builder +!FILEBROWSER_EXTPROGMENU;Open with +!FILEBROWSER_FLATFIELD;Flat Field +!FILEBROWSER_MOVETODARKFDIR;Move to dark frames directory +!FILEBROWSER_MOVETOFLATFIELDDIR;Move to flat fields directory +!FILEBROWSER_NEW_NAME;New name: +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!FILEBROWSER_POPUPCOLORLABEL0;Label: None +!FILEBROWSER_POPUPCOLORLABEL1;Label: Red +!FILEBROWSER_POPUPCOLORLABEL2;Label: Yellow +!FILEBROWSER_POPUPCOLORLABEL3;Label: Green +!FILEBROWSER_POPUPCOLORLABEL4;Label: Blue +!FILEBROWSER_POPUPCOLORLABEL5;Label: Purple +!FILEBROWSER_POPUPCOLORLABEL;Color label +!FILEBROWSER_POPUPCOPYTO;Copy to... +!FILEBROWSER_POPUPFILEOPERATIONS;File Operations +!FILEBROWSER_POPUPMOVETO;Move to... +!FILEBROWSER_POPUPPROCESSFAST;Put to Queue (Fast export) +!FILEBROWSER_POPUPPROFILEOPERATIONS;Processing Profile Operations +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_POPUPREMOVESUBMENU;Remove +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!FILEBROWSER_QUERYHINT;Type a partial filename to search for.\nCtrl-F to focus the Find text box (in the File Browser).\nEnter to commence search. +!FILEBROWSER_QUERYLABEL; Find: +!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 +!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-` +!FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +!FILEBROWSER_USETEMPLATE;Use template: +!GENERAL_AFTER;After +!GENERAL_BEFORE;Before +!GENERAL_FILE;File +!GENERAL_HIGH_QUALITY;High Quality +!GENERAL_NONE;None +!GENERAL_UNCHANGED;(Unchanged) +!GENERAL_WARNING;Warning +!HISTOGRAM_BUTTON_BAR;RGB +!HISTOGRAM_BUTTON_B;B +!HISTOGRAM_BUTTON_G;G +!HISTOGRAM_BUTTON_L;L +!HISTOGRAM_BUTTON_RAW;Raw +!HISTOGRAM_BUTTON_R;R +!HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar\nClick right mouse button on image preview to freeze/unfreeze +!HISTOGRAM_TOOLTIP_FULL;Toggle full or scaled histogram +!HISTOGRAM_TOOLTIP_RAW;Show/Hide raw histogram +!HISTORY_MSG_82;Profile Changed +!HISTORY_MSG_83;High Quality Shadows/Highlights +!HISTORY_MSG_84;Perspective Correction +!HISTORY_MSG_85;Lens Correction Profile +!HISTORY_MSG_86;Wavelet Equalizer +!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 +!HISTORY_MSG_92;NR - Gamma +!HISTORY_MSG_93;Contrast by Detail Levels Value +!HISTORY_MSG_94;Contrast by Detail Levels +!HISTORY_MSG_95;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;RGB Saturation +!HISTORY_MSG_101;HSV EQ -- Hue +!HISTORY_MSG_102;HSV EQ -- Saturation +!HISTORY_MSG_103;HSV EQ -- Value +!HISTORY_MSG_104;HSV Equalizer +!HISTORY_MSG_105;Defringing +!HISTORY_MSG_106;Defringing Radius +!HISTORY_MSG_107;Defringing Threshold +!HISTORY_MSG_108;Highlight Compr. Threshold +!HISTORY_MSG_109;Resize Bounding Box +!HISTORY_MSG_110;Resizing applies o +!HISTORY_MSG_111;Avoid Color Shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;Red and Skin Tones Protection +!HISTORY_MSG_114;DCB Iterations +!HISTORY_MSG_115;False Color Iterations +!HISTORY_MSG_116;Enhanced DCB +!HISTORY_MSG_117;Red CA Correction +!HISTORY_MSG_118;Blue CA Correction +!HISTORY_MSG_119;Line Denoise +!HISTORY_MSG_120;Green Equil. Threshold +!HISTORY_MSG_121;Auto CA +!HISTORY_MSG_122;Auto Dark Frame +!HISTORY_MSG_123;Dark Frame File +!HISTORY_MSG_124;Linear Exp. Correction +!HISTORY_MSG_125;Exp. Correction Preserving HL +!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;Gamma +!HISTORY_MSG_134;Gamma Position +!HISTORY_MSG_135;Gamma Free +!HISTORY_MSG_136;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 Green Together +!HISTORY_MSG_142;Edges Sharpening - Iterations +!HISTORY_MSG_143;Edges Sharpening - Quantity +!HISTORY_MSG_144;Microcontrast - Quantity +!HISTORY_MSG_145;Microcontrast - Uniformity +!HISTORY_MSG_146;Edges Sharpening +!HISTORY_MSG_147;Edges Sharpening - 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;Vibrance - Pastel tones +!HISTORY_MSG_153;Vibrance - Saturated tones +!HISTORY_MSG_154;Vibrance - Protect skin tones +!HISTORY_MSG_155;Vibrance - Avoid color drift +!HISTORY_MSG_156;Vibrance - Link pastel and saturated tones +!HISTORY_MSG_157;Vibrance - Pastel/Saturated threshold +!HISTORY_MSG_158;Strength +!HISTORY_MSG_159;Edge Stopping +!HISTORY_MSG_160;Scale +!HISTORY_MSG_161;Reweighting Iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_163;RGB Curves - R +!HISTORY_MSG_164;RGB Curves - G +!HISTORY_MSG_165;RGB Curves - B +!HISTORY_MSG_166;Neutral Levels +!HISTORY_MSG_167;B&W Toning +!HISTORY_MSG_168;'Cc' curve +!HISTORY_MSG_169;'Ch' curve +!HISTORY_MSG_170;Vibrance - Curve +!MAIN_BUTTON_FULLSCREEN;Fullscreen +!MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Put current image to processing queue.\nShortcut: Ctrl+Q +!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_ERRORDURINGIMAGESAVING;Error during image saving +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue processed first. +!MAIN_MSG_NAVIGATOR;Navigator +!MAIN_MSG_PLACES;Places +!MAIN_TAB_COLOR_TOOLTIP;Shortcut: Alt-C +!MAIN_TAB_DETAIL_TOOLTIP;Shortcut: Alt-D +!MAIN_TAB_EXPORT; 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_TOGGLE_BEFORE_AFTER;B|A +!MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 8 +!MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 0 +!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_CHANNELMIXER;Channel mixer +!PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto fill +!PARTIALPASTE_DARKFRAMEAUTOSELECT;Dark Frame Auto Select +!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;FF Auto Select +!PARTIALPASTE_FLATFIELDBLURRADIUS;FF Blur Radius +!PARTIALPASTE_FLATFIELDBLURTYPE;FF Blur Type +!PARTIALPASTE_FLATFIELDFILE;Flat field (FF) File +!PARTIALPASTE_HLRECONSTRUCTION;Highlight reconstruction +!PARTIALPASTE_HLRECOVERYAMOUNT;Highlight recovery amount +!PARTIALPASTE_HLRECOVERYTHRESHOLD;Highlight recovery threshold +!PARTIALPASTE_HSVEQUALIZER;HSV Equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!PARTIALPASTE_LABCURVE;Lab adjustments +!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 Level +!PARTIALPASTE_RAWEXPOS_LINEAR;Raw white point linear corr. factor +!PARTIALPASTE_RAWEXPOS_PRESER;Raw white point HL preserving corr. (EV) +!PARTIALPASTE_RAWGROUP;Raw settings +!PARTIALPASTE_RAW_ALLENHANCE;Apply post demosaic artifact/noise reduction +!PARTIALPASTE_RAW_DCBENHANCE;Apply DCB enhancement step +!PARTIALPASTE_RAW_DCBITERATIONS;Number of DCB iterations +!PARTIALPASTE_RAW_DMETHOD;Demosaic Method +!PARTIALPASTE_RAW_FALSECOLOR;Demosaic False color suppression steps +!PARTIALPASTE_RGBCURVES;RGB curves +!PARTIALPASTE_SHARPENEDGE;Edges +!PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_VIBRANCE;Vibrance +!PARTIALPASTE_WAVELETEQUALIZER;Wavelet equalizer +!PREFERENCES_ADD;ADD +!PREFERENCES_AUTOMONPROFILE;Automatically use operating system's main monitor color profile +!PREFERENCES_BATCH_PROCESSING;Batch Processing +!PREFERENCES_BEHAVIOR;Behavior +!PREFERENCES_CUSTPROFBUILDHINT;Executable (or script) file called when a new initial processing profile should be generated for an image.\nReceives command line parameters to allow a rules-based processing profile generation:\n[raw/JPG path] [default processing profile path] [f-number] [exposure in secs] [focal length in mm] [ISO] [lens] [camera] +!PREFERENCES_CUSTPROFBUILDPATH;Executable path +!PREFERENCES_CUSTPROFBUILD;Custom Processing Profile Builder +!PREFERENCES_CUTOVERLAYBRUSH;Crop mask color/transparency +!PREFERENCES_DARKFRAMEFOUND;Found +!PREFERENCES_DARKFRAMESHOTS;shots +!PREFERENCES_DARKFRAMETEMPLATES;templates +!PREFERENCES_DARKFRAME;Dark Frame +!PREFERENCES_DATEFORMATFRAME;Date Format +!PREFERENCES_DIRDARKFRAMES;Dark frames directory +!PREFERENCES_EDITORLAYOUT;Editor Layout +!PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar (de-select for low res display) +!PREFERENCES_FLATFIELDFOUND;Found +!PREFERENCES_FLATFIELDSDIR;Flat Fields directory +!PREFERENCES_FLATFIELDSHOTS;shots +!PREFERENCES_FLATFIELDTEMPLATES;templates +!PREFERENCES_FLATFIELD;Flat Field +!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_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). On Windows use "SystemDefault", "SystemAsterisk" etc. for system sounds. +!PREFERENCES_SND_LNGEDITPROCDONE;Editor processing done +!PREFERENCES_SND_TRESHOLDSECS;after secs +!PREFERENCES_SQUAREDETAILWINDOW;Square detail window (faster) +!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_USESYSTEMTHEME; Use system theme +!PREFERENCES_WORKFLOW;Layout +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_SAVEPPASTE;Parameters to save +!PROGRESSBAR_BADPIXELS;Bad pixels... +!PROGRESSBAR_CACORRECTION;CA correction... +!PROGRESSBAR_DARKFRAME;Darkframe... +!PROGRESSBAR_GREENEQUIL;Green equilibrate... +!PROGRESSBAR_LINEDENOISE;Line Denoise... +!PROGRESSBAR_LOADINGTHUMBS;Loading thumbnails... +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing Profile Saved +!PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists +!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\nthe 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_CHROMATABERR_LABEL;Chromatic Aberration +!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_DETAIL_AMOUNT;Amount +!TP_DIRPYRDENOISE_CHROMA;Chrominance +!TP_DIRPYRDENOISE_GAMMA;Gamma +!TP_DIRPYRDENOISE_LABEL;Noise reduction +!TP_DIRPYRDENOISE_LUMA;Luminance +!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_EQUALIZER_CONTRAST_MINUS;Contrast- +!TP_EQUALIZER_CONTRAST_PLUS;Contrast+ +!TP_EQUALIZER_FINEST;finest +!TP_EQUALIZER_LABEL;Wavelet equalizer +!TP_EQUALIZER_LARGEST;coarsest +!TP_EQUALIZER_NEUTRAL;Neutral +!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 +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in auto levels operation +!TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Highlight recovery threshold +!TP_EXPOSURE_SATURATION;Saturation +!TP_EXPO_AFTER; After interpolation (before RGB conversion) +!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_HLREC_BLEND;Blend +!TP_HSVEQUALIZER_CHANNEL;HSV Channel +!TP_HSVEQUALIZER_HUE;H +!TP_HSVEQUALIZER_LABEL;HSV Equalizer +!TP_HSVEQUALIZER_NEUTRAL;Neutral +!TP_HSVEQUALIZER_SAT;S +!TP_HSVEQUALIZER_VAL;V +!TP_ICM_BLENDCMSMATRIX;Blend highlights with matrix +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover blown highlights when using LUT based ICC profiles +!TP_ICM_INPUTCAMERAICC;Auto-matched camera-specific color profile +!TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profile. These profiles are more precise than simpler matrix ones. Available for some 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_PREFERREDPROFILE;Preferred DCP profile +!TP_ICM_PREFERREDPROFILE_1;Daylight +!TP_ICM_PREFERREDPROFILE_2;Tungsten +!TP_ICM_PREFERREDPROFILE_3;Fluorescent +!TP_ICM_PREFERREDPROFILE_4;Flash +!TP_IMPULSEDENOISE_LABEL;Impulse Noise Reduction +!TP_IMPULSEDENOISE_THRESH;Impulse NR Threshold +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid Color Shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space\nand apply Munsell correction +!TP_LABCURVE_BRIGHTNESS;Brightness +!TP_LABCURVE_BWTONING;B&W Toning +!TP_LABCURVE_BWTONING_TIP;With B&W Toning option enabled, the Lab Chromaticity, Cc and Ch curves are not in effect.\nToning can be achieved using the a and b curves +!TP_LABCURVE_CHROMATICITY;Chromaticity +!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 the Chromaticity +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to the Hue +!TP_LABCURVE_LABEL;Lab Adjustments +!TP_LABCURVE_RSTPROTECTION;Red and Skin Tones Protection +!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;Use CA correction +!TP_LENSPROFILE_USEDIST;Use distortion correction +!TP_LENSPROFILE_USEVIGN;Use vignette correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset exposure controls to neutral values +!TP_PERSPECTIVE_HORIZONTAL;Horizontal +!TP_PERSPECTIVE_LABEL;Perspective +!TP_PERSPECTIVE_VERTICAL;Vertical +!TP_PREPROCESS_GREENEQUIL;Green equilibration +!TP_PREPROCESS_HOTDEADPIXFILT;Apply hot/dead pixel filter +!TP_PREPROCESS_HOTDEADPIXTHRESH;Hot/dead pixel detection threshold +!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 (leader) +!TP_RAWEXPOS_LINEAR;White Point: Linear corr. factor +!TP_RAWEXPOS_PRESER;White Point: HL preserving corr.(EV) +!TP_RAWEXPOS_TWOGREEN;Two greens together +!TP_RAW_ALLENHANCE;Apply post demosaic artifact/noise reduction +!TP_RAW_DCBENHANCE;Apply DCB enhancement step +!TP_RAW_DCBITERATIONS;Number of DCB iterations +!TP_RAW_LABEL;Demosaicing +!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_RED;R +!TP_SHARPENEDGE_AMOUNT;Quantity +!TP_SHARPENEDGE_LABEL;Edges +!TP_SHARPENEDGE_PASSES;Iterations +!TP_SHARPENEDGE_THREE;Luminance only +!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 the Hue +!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_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 +!ZOOMPANEL_100;(100%) +!ZOOMPANEL_NEWCROPWINDOW;Open (new) detail window +!ZOOMPANEL_ZOOM100;Zoom to 100% 1 +!ZOOMPANEL_ZOOMFITSCREEN;Fit to screen F +!ZOOMPANEL_ZOOMIN;Zoom In + +!ZOOMPANEL_ZOOMOUT;Zoom Out - diff --git a/rtdata/languages/README b/rtdata/languages/README new file mode 100644 index 000000000..e13360074 --- /dev/null +++ b/rtdata/languages/README @@ -0,0 +1,67 @@ +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 ~/rawtherapee/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..d4a35fc04 --- /dev/null +++ b/rtdata/languages/Russian @@ -0,0 +1,1227 @@ + +ABOUT_TAB_BUILD;Версия +ABOUT_TAB_CREDITS;Авторы +ABOUT_TAB_LICENSE;Лицензия +ABOUT_TAB_RELEASENOTES;Примечания к выпуску +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;Управляющая 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_DIALOGLABEL;Фильтр Exif +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_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_ARRANGEMENTHINT;Вертикальное/горизонтальное расположение эскизов +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_COPYPROFILE;Скопировать профиль +FILEBROWSER_CURRENT_NAME;Текущее имя: +FILEBROWSER_DARKFRAME;Темновой кадр +FILEBROWSER_DELETEDLGLABEL;Подтверждение удаления файла +FILEBROWSER_DELETEDLGMSGINCLPROC;Вы уверены, что хотите удалить %1 выделенных файлов, включая обработанные версии? +FILEBROWSER_DELETEDLGMSG;Вы уверены, что хотите удалить %1 выбранный(ых) файл(ов)? +FILEBROWSER_EMPTYTRASHHINT;Удалить файлы из корзины без возможности восстановления +FILEBROWSER_EMPTYTRASH;Очистить корзину +FILEBROWSER_EXEC_CPB;Создание собственного профиля +FILEBROWSER_EXIFFILTERAPPLYHINT;Включение/выключения фильтра Exif в браузере +FILEBROWSER_EXIFFILTERAPPLY;Применить +FILEBROWSER_EXIFFILTERLABEL;Фильтр Exif +FILEBROWSER_EXIFFILTERSETTINGSHINT;Настройка параметров фильтра Exif +FILEBROWSER_EXIFFILTERSETTINGS;Настройка +FILEBROWSER_EXTPROGMENU;Открыть с помощью +FILEBROWSER_FLATFIELD;Плоское поле +FILEBROWSER_MOVETODARKFDIR;Переместить в папку темных кадров +FILEBROWSER_MOVETOFLATFIELDDIR;Переместить в папку с файлами плоских полей +FILEBROWSER_NEW_NAME;Новое имя: +FILEBROWSER_OPENDEFAULTVIEWER;Программа просмотра в Windows по умолчанию (обрабатывающая очереди) +FILEBROWSER_PARTIALPASTEPROFILE;Частичная вставка +FILEBROWSER_PASTEPROFILE;Вставка профиля +FILEBROWSER_POPUPCANCELJOB;Отменить задание +FILEBROWSER_POPUPCOLORLABEL0;Пометка: нет +FILEBROWSER_POPUPCOLORLABEL1;Пометка: Красным +FILEBROWSER_POPUPCOLORLABEL2;Пометка: Желтым +FILEBROWSER_POPUPCOLORLABEL3;Пометка: Зеленым +FILEBROWSER_POPUPCOLORLABEL4;Пометка: Синим +FILEBROWSER_POPUPCOLORLABEL5;Пометка: Фиолетовым +FILEBROWSER_POPUPCOLORLABEL;Цветовая пометка +FILEBROWSER_POPUPCOPYTO;Скопировать в... +FILEBROWSER_POPUPFILEOPERATIONS;Действия с файлами +FILEBROWSER_POPUPMOVEEND;Переместить в конец очереди +FILEBROWSER_POPUPMOVEHEAD;Переместить в начало очереди +FILEBROWSER_POPUPMOVETO;Переместить в... +FILEBROWSER_POPUPOPEN;Открыть +FILEBROWSER_POPUPPROCESSFAST;Поставить в очередь (Быстрый экспорт) +FILEBROWSER_POPUPPROCESS;Поместить в очередь на обработку +FILEBROWSER_POPUPPROFILEOPERATIONS;Обработка операций профиля +FILEBROWSER_POPUPRANK1;Рейтинг 1 +FILEBROWSER_POPUPRANK2;Рейтинг 2 +FILEBROWSER_POPUPRANK3;Рейтинг 3 +FILEBROWSER_POPUPRANK4;Рейтинг 4 +FILEBROWSER_POPUPRANK5;Рейтинг 5 +FILEBROWSER_POPUPREMOVEINCLPROC;Удалить из файловой системы и результатов пакетной обработки +FILEBROWSER_POPUPREMOVESUBMENU;Удалить +FILEBROWSER_POPUPREMOVE;Удалить с диска +FILEBROWSER_POPUPRENAME;Переименовать +FILEBROWSER_POPUPSELECTALL;Выбрать все +FILEBROWSER_POPUPTRASH;Удалить в корзину +FILEBROWSER_POPUPUNRANK;Снять рейтинг +FILEBROWSER_POPUPUNTRASH;Удалить из корзины +FILEBROWSER_PROCESSINGSETTINGSHINT;Задать формат файла и выходной каталог +FILEBROWSER_PROCESSINGSETTINGS;Параметры +FILEBROWSER_QUERYBUTTONHINT;Очистить поисковой запрос +FILEBROWSER_QUERYHINT;Введите часть искомого имени файла.\nCtrl-F для переключения на диалог поиска текста (в Обозревателе файлов).\nEnter для начала поиска. +FILEBROWSER_QUERYLABEL; Найти: +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;Показать все изображения в каталоге +FILEBROWSER_SHOWEDITEDHINT;Показать измененные изображения.\nГорячая клавиша: 7 +FILEBROWSER_SHOWEDITEDNOTHINT;Показать не измененные изображения.\nГорячая клавиша: 6 +FILEBROWSER_SHOWEXIFINFO;Показать EXIF i +FILEBROWSER_SHOWQUEUEHINT;Показать содержимое очереди на обработку +FILEBROWSER_SHOWRANK1HINT;Показать изображения с рейтингом 1 +FILEBROWSER_SHOWRANK2HINT;Показать изображения с рейтингом 2 +FILEBROWSER_SHOWRANK3HINT;Показать изображения с рейтингом 3 +FILEBROWSER_SHOWRANK4HINT;Показать изображения с рейтингом 4 +FILEBROWSER_SHOWRANK5HINT;Показать изображения с рейтингом 5 +FILEBROWSER_SHOWRECENTLYSAVEDHINT;Показать недавно сохраненные изображения.\nГорячая клавиша: Alt-7 +FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Показать не недавно сохраненные изображения.\nГорячая клавиша: Alt-6 +FILEBROWSER_SHOWTRASHHINT;Показать содержимое корзины +FILEBROWSER_SHOWUNCOLORHINT;Показать изображения без цветовой метки.\nГорячая клавиша: Alt-` +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_HIGH_QUALITY;Высокое качество +GENERAL_LANDSCAPE;Альбомный +GENERAL_LOAD;Загрузить +GENERAL_NA;Н/Д +GENERAL_NONE;Нет +GENERAL_NO;Нет +GENERAL_OK;OK +GENERAL_PORTRAIT;Портретный +GENERAL_SAVE;Сохранить +GENERAL_UNCHANGED;(не менялось) +GENERAL_YES;Да +HISTOGRAM_BUTTON_BAR;RGB +HISTOGRAM_BUTTON_B;B +HISTOGRAM_BUTTON_G;G +HISTOGRAM_BUTTON_L;L +HISTOGRAM_BUTTON_RAW;Raw +HISTOGRAM_BUTTON_R;R +HISTOGRAM_LABEL;Гистограмма +HISTOGRAM_TOOLTIP_BAR;Показать/скрыть панель отображения RGB\nНажмите правую кнопку мыши на предпросмотре изображения, чтобы заблокировать/разблокировать его +HISTOGRAM_TOOLTIP_B;Показать/скрыть СИНИЙ канал гистограммы +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;Тоновая кривая +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;Данные изменения размеров +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;Контраст по уровням детализации +HISTORY_MSG_95;Насыщенность +HISTORY_MSG_96;Кривая 'a' +HISTORY_MSG_97;Кривая 'b' +HISTORY_MSG_98;Демозаика +HISTORY_MSG_99;Фильтр засвеченных/битых пикселей +HISTORY_MSG_100;RGB насыщенность +HISTORY_MSG_101;HSV EQ -- Цветовой тон +HISTORY_MSG_102;HSV EQ -- Насыщенность +HISTORY_MSG_103;HSV EQ -- Яркость +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;Избегать сдвига цвета +HISTORY_MSG_112;Ограничитель насыщенности +HISTORY_MSG_113;Предел насыщенности +HISTORY_MSG_114;Проходы DCB +HISTORY_MSG_115;Проходы ложного цвета +HISTORY_MSG_116;Расширенная DCB +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;Коррекция экспозиции сохраняет 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;Microcontrast - Равномерность +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_NEWSNAPSHOTAS;Как... +HISTORY_NEWSNAPSHOT;Новый снимок +HISTORY_NEWSSDIALOGLABEL;Название снимка: +HISTORY_NEWSSDIALOGTITLE;Добавить снимок +HISTORY_SETTO;Установить в +HISTORY_SNAPSHOTS;Снимки +HISTORY_SNAPSHOT;Снимок +ICMPANEL_FILEDLGFILTERANY;Любые файлы +ICMPANEL_FILEDLGFILTERICM;Файлы ICC профилей +ICMPANEL_GAMMABEFOREINPUT;Применять гамму для профиля +ICMPANEL_INPUTCAMERA;По умолчанию для камеры +ICMPANEL_INPUTCUSTOM;Пользовательский +ICMPANEL_INPUTDLGLABEL;Выберите входной ICC профиль... +ICMPANEL_INPUTEMBEDDED;Использовать встроенный, если это возможно +ICMPANEL_INPUTPROFILE;Входной профиль +ICMPANEL_NOICM;Без ICM: sRGB на выходе +ICMPANEL_OUTPUTDLGLABEL;Выберите выходной ICC профиль... +ICMPANEL_OUTPUTPROFILE;Выходной профиль +ICMPANEL_SAVEREFERENCE;Сохранить исходное изображение для профилирования +ICMPANEL_WORKINGPROFILE;Рабочий профиль +IMAGEAREA_DETAILVIEW;Детальный просмотр +IPTCPANEL_AUTHORHINT;Имя создателя объекта (писателя, фотографа или художника) (By-line) +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_EXIT;Выход +MAIN_BUTTON_FULLSCREEN;Полный экран +MAIN_BUTTON_PREFERENCES;Настройки +MAIN_BUTTON_PUTTOQUEUE;В очередь +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Поместить текущее изображение в очередь на обработку Ctrl+Q +MAIN_BUTTON_QUEUE;В очередь +MAIN_BUTTON_SAVEAS;Сохранить как... +MAIN_BUTTON_SAVE;Сохранить +MAIN_BUTTON_SAVE_TOOLTIP;Сохранить текущее изображение Ctrl+S +MAIN_BUTTON_SENDTOEDITOR;Открыть в редакторе +MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Редактировать изображение во внешнем редакторе Ctrl+E +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;Недавние папки +MAIN_MSG_ALREADYEXISTS;Файл уже существует. +MAIN_MSG_CANNOTLOAD;Невозможно загрузить изображение +MAIN_MSG_CANNOTSAVE;Ошибка при сохранении файла +MAIN_MSG_CANNOTSTARTEDITOR;не удалось запустить редактор. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Пожалуйста, установите правильный каталог в диалоге "Настройки". +MAIN_MSG_EMPTYFILENAME;Имя файла не указано! +MAIN_MSG_ERRORDURINGIMAGESAVING;Ошибка при сохранении изображения +MAIN_MSG_EXITJOBSINQUEUEINFO;Необработанные изображения, находящиеся в очереди,будут утеряны при выходе из программы. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Вы уверены, что хотите выйти из программы? В очереди остались необработанные изображения. +MAIN_MSG_IMAGEUNPROCESSED;Для выполнения этой команды нужно, чтобы все выбранные изображения сперва были обработан в очереди. +MAIN_MSG_JOBSINQUEUE;Идёт обработка +MAIN_MSG_NAVIGATOR;Навигатор +MAIN_MSG_PLACES;Закладки +MAIN_MSG_QOVERWRITE;Вы хотите перезаписать его? +MAIN_TAB_BASIC;Основные +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_ICM;ICM +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_TOGGLE_BEFORE_AFTER;Д|П +MAIN_TOOLTIP_BEFOREAFTERLOCK;Забокировать / Разблокировать предыдущий вид\n\nЗабокировать: сохраняет предыдущий вид неизменным.\nПолезно для оценки общего эффетка от применения нескольких инструментов.\nК тому же, сравнения могут быть произведены на любом состоянии истории\n\nРазблокировать: предыдущий вид будет следовать сразу за следующим, показывая состояние изображения до применения текущего инструмента. +MAIN_TOOLTIP_HIDEFP;Показать/скрыть нижнюю панель (каталоги и список файлов, горячая клавиша: F) +MAIN_TOOLTIP_HIDEHP;Показать/скрыть левую панель (включая историю, горячая клавиша: H) +MAIN_TOOLTIP_INDCLIPPEDH;Индикатор пересветов +MAIN_TOOLTIP_INDCLIPPEDS;Индикатор затемнений +MAIN_TOOLTIP_PREFERENCES;задать настройки +MAIN_TOOLTIP_PREVIEWB;Просмотреть канал синего.\nГорячая клавиша: b +MAIN_TOOLTIP_PREVIEWFOCUSMASK;Просмотреть Маску резкости.\nГорячая клавиша: Shift-F\n\nБолее точна на изображениях с небольшой глубиной резкости, малым шумом и на большом зуме отображения\n\nДля улучшения определения на шумных изображениях используйте на маленьком зуме 10-30%\n\nПредпросмотр просчитывается медленнее со включенной маской резкости. +MAIN_TOOLTIP_PREVIEWG;Preview the канал зеленого.\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;Информация об изображении +MAIN_TOOLTIP_SAVEAS;Сохранить изображение в... +MAIN_TOOLTIP_SAVE;Сохранить изображение в каталог по умолчанию +MAIN_TOOLTIP_SHOWHIDELP1;Показать/скрыть левую панель l +MAIN_TOOLTIP_SHOWHIDERP1;Показать/скрыть правую панель Alt-l +MAIN_TOOLTIP_SHOWHIDETP1;Показать/скрыть верхнюю панель Shift-l +MAIN_TOOLTIP_THRESHOLD;Порог +MAIN_TOOLTIP_TOGGLE;Включить режим "до/после" 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_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_CHANNELMIXER;Смешение каналов +PARTIALPASTE_COARSETRANS;поворот на 90 гр. / отражение +PARTIALPASTE_COLORBOOST;Усиление цвета +PARTIALPASTE_COLORDENOISE;Удаление цветового шума +PARTIALPASTE_COLORGROUP;Настройка цвета +PARTIALPASTE_COLORMIXER;Цветовой микшер +PARTIALPASTE_COLORSHIFT;Цветовой сдвиг +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_HLRECONSTRUCTION;Восстановление пересветов +PARTIALPASTE_HLRECOVERYAMOUNT;Сила восстановления пересветов +PARTIALPASTE_HLRECOVERYTHRESHOLD;Порог восстановления пересветов +PARTIALPASTE_HLRECOVERY;Восстановление светов +PARTIALPASTE_HSVEQUALIZER;HSV Эквалайзер +PARTIALPASTE_ICMGAMMA;Выходная гамма +PARTIALPASTE_ICMSETTINGS;Параметры ICM +PARTIALPASTE_IMPULSEDENOISE;Подавление импульсного шума +PARTIALPASTE_IPTCINFO;Данные IPTC +PARTIALPASTE_LABCURVE;Кривые в пространстве Lab +PARTIALPASTE_LENSGROUP;Параметры съемки +PARTIALPASTE_LUMACURVE;Кривая яркости +PARTIALPASTE_LUMADENOISE;Удаление яркостного шума +PARTIALPASTE_LUMINANCEGROUP;Настройка параметров яркости +PARTIALPASTE_METAICMGROUP;Настройка метаданных/параметров ICM +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;Сохраняющая HL Raw white point HL preserving corr. (EV) +PARTIALPASTE_RAWGROUP;Настройки Raw +PARTIALPASTE_RAW_ALLENHANCE;Применить После-демозаичный артефакт/Подавление шума +PARTIALPASTE_RAW_DCBENHANCE;Применить улучшающий подход DCB +PARTIALPASTE_RAW_DCBITERATIONS;Количество проходов DCB +PARTIALPASTE_RAW_DMETHOD;Методика демозаики +PARTIALPASTE_RAW_FALSECOLOR;Шагов демозаичного подавления ложных цветов: +PARTIALPASTE_RESIZE;Изменение размера +PARTIALPASTE_RGBCURVES;Кривые RGB +PARTIALPASTE_ROTATION;Поворот +PARTIALPASTE_SHADOWSHIGHLIGHTS;Тени/света +PARTIALPASTE_SHARPENEDGE;Края +PARTIALPASTE_SHARPENING;Повышение резкости +PARTIALPASTE_SHARPENMICRO;Микроконтраст +PARTIALPASTE_VIBRANCE;Резонанс +PARTIALPASTE_VIGNETTING;Коррекция виньетирования +PARTIALPASTE_WAVELETEQUALIZER;Вейвлет эквалайзер +PARTIALPASTE_WHITEBALANCE;Баланс белого +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_CACHESTRAT1;Выше скорость - больше расход ОЗУ +PREFERENCES_CACHESTRAT2;Меньше расход памяти - скорость ниже +PREFERENCES_CACHESTRAT;Стратегия кэширования +PREFERENCES_CACHETHUMBFORM;Формат кэширования эскизов +PREFERENCES_CACHETHUMBHEIGHT;Максимальная высота эскиза +PREFERENCES_CLEARDLG_LINE1;Очистка кэша +PREFERENCES_CLEARDLG_LINE2;Это может занять несколько секунд. +PREFERENCES_CLEARDLG_TITLE;Пожалуйста, подождите +PREFERENCES_CLIPPINGIND;Индикация пересветов/затемнений +PREFERENCES_CMETRICINTENT;Колориметрическое преобразование +PREFERENCES_CUSTPROFBUILDHINT;Исполняемый (или скриптовой) файл, вызываемый, когда для изображения должен быть сгенерирован новый профиль обработки.\nПередаваемые командной строкой параметры для предоставления возможности создания профиля обработки на основе правил:\n[путь к raw/JPG] [путь к профилю обработки по умолчанию] [f-число] [выдержка в сек.] [фокусное расст. в мм] [ISO] [объектив] [камера] +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%y/%m/%d +PREFERENCES_DATEFORMAT;Формат даты +PREFERENCES_DEFAULTLANG;Язык по умолчанию +PREFERENCES_DEFAULTTHEME;Тема по умолчанию +PREFERENCES_DEMOSAICINGALGO;Алгоритм получения изображения +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_FORIMAGE;Для изображений +PREFERENCES_FORRAW;Для RAW файлов +PREFERENCES_GIMPPATH;Каталог установки GIMP +PREFERENCES_GTKTHEME;GTK по умолчанию +PREFERENCES_HINT;Подсказка +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_LIVETHUMBNAILS;Эскизы в реальном времени (медленно) +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_OUTDIRHINT;Вы можете использовать следующие элементы форматирования:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nЭти элементы соответствуют каталогам и подкаталогам в пути к RAW-файлу.\n\nНапример, если путь к файлу - /home/tom/image/02-09-2006/dsc0012.nef, то элементы форматирования будут следующими:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nЕсли вы хотите сохранять изображения в один каталог с оригиналом, введите строку:\n%p1/%f\n\nЕсли вы хотите сохранять изображения в подкаталог "converted" в каталоге оригинального файла, введите строку:\n%p1/converted/%f\n\nДля сохранения изображений в каталог "/home/tom/converted" с сохранением подкаталогов с датами, введите строку:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATEHINT;Вы можете использовать следующие элементы форматирования:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nЭти элементы соответствуют каталогам и подкаталогам в пути к RAW-файлу.\n\nНапример, если был открыт каталог /home/tom/image/02-09-2006/dsc0012.nef, то элементы форматирования будут выглядеть так:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nЕсли вы хотите сохранять изображения в каталоге с оригиналом, введите:\n%p1/%f\n\nЕсли вы хотите сохранять изображения в каталоге "converted", расположенной в каталоге оригинального файла, введите строку:\n%p1/converted/%f\n\nДля сохранения изображений папке в "/home/tom/converted" с сохранением подкаталогов с датами, введите строку:\n%p2/converted/%d1/%f +PREFERENCES_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_SELECTFONT;Выбрать шрифт +PREFERENCES_SELECTICCDIRDLG;Выберите каталог для ICC профиля... +PREFERENCES_SELECTLANG;Выберите язык +PREFERENCES_SELECTMONITORPROFDLG;Выберите каталог для ICC профиля монитора... +PREFERENCES_SELECTTHEME;Выбрать тему +PREFERENCES_SET;Установить +PREFERENCES_SHOWBASICEXIF;Показывать основные Exif данные +PREFERENCES_SHOWDATETIME;Показывать дату и время +PREFERENCES_SHOWEXPOSURECOMPENSATION;Добавить компенсацию выдержки +PREFERENCES_SHOWONLYRAW;Показывать только RAW-файлы +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_OUTPUT;Сохранение +PREFERENCES_TAB_SOUND;Звуки +PREFERENCES_THUMBSIZE;Размер миниатюры +PREFERENCES_TP_LABEL;Панель инструментов: +PREFERENCES_TP_USEICONORTEXT;Использовать в закладках иконки вместо текста +PREFERENCES_TP_VSCROLLBAR;Спрятать вертикальную полосу прокрутки +PREFERENCES_TUNNELMETADATA;Скопировать IPTC/XMP в неизменном виде в выходной файл (если используете внешние программы каталогизации) +PREFERENCES_USESYSTEMTHEME;Использовать системную тему оформления +PREFERENCES_WORKFLOW;Стиль работы +PROFILEPANEL_COPYPPASTE;Параметры для копирования +PROFILEPANEL_FILEDLGFILTERANY;Любые файлы +PROFILEPANEL_FILEDLGFILTERPP;Профили обработки +PROFILEPANEL_LABEL;Профиль обработки +PROFILEPANEL_LOADDLGLABEL;Загрузить профиль обработки... +PROFILEPANEL_LOADPPASTE;Параметры для загрузки +PROFILEPANEL_PASTEPPASTE;Параметры для вставки +PROFILEPANEL_PCUSTOM;Пользовательский +PROFILEPANEL_PFILE;Из файла +PROFILEPANEL_PLASTPHOTO;Из прошлого изображения +PROFILEPANEL_PLASTSAVED;Послед. сохр. +PROFILEPANEL_PROFILE;Профиль +PROFILEPANEL_SAVEDLGLABEL;Сохранить профиль обработки... +PROFILEPANEL_SAVEPPASTE;Параметры для сохранения +PROFILEPANEL_TOOLTIPCOPY;Скопировать текущий профиль в буфер обмена +PROFILEPANEL_TOOLTIPLOAD;Загрузить профиль из файла +PROFILEPANEL_TOOLTIPPASTE;Вставить профиль из буфера обмена +PROFILEPANEL_TOOLTIPSAVE;Сохранить текущий профиль +PROGRESSBAR_BADPIXELS;Битые пиксели... +PROGRESSBAR_CACORRECTION;Коррекция ХА... +PROGRESSBAR_DARKFRAME;Темновой кадр... +PROGRESSBAR_DECODING;Декодирование RAW файла... +PROGRESSBAR_DEMOSAICING;Построение изображения... +PROGRESSBAR_GREENEQUIL;Выравнивание зелёного... +PROGRESSBAR_LINEDENOISE;Линейное удаление шума... +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;Сохранение файла... +QINFO_FOCALLENGTH;Фокусное расстояние +QINFO_ISO;ISO +QINFO_LENS;Объектив +QINFO_NOEXIF;Данные Exif недоступны +SAVEDLG_AUTOSUFFIX;Автоматически добавлять суффикс если файл существует +SAVEDLG_FILEFORMAT;Формат файла +SAVEDLG_JPEGQUAL;Качество JPEG +SAVEDLG_JPGFILTER;Файлы JPEG +SAVEDLG_PNGCOMPR;Сжатие PNG +SAVEDLG_PNGFILTER;Файлы PNG +SAVEDLG_PUTTOQUEUEHEAD;Поместить в начало очереди на обработку +SAVEDLG_PUTTOQUEUETAIL;Поместить в конец очереди на обработку +SAVEDLG_PUTTOQUEUE;Поместить в очередь на обработку +SAVEDLG_SAVEIMMEDIATELY;Сохранить сейчас +SAVEDLG_SAVESPP;Сохранять параметры обработки вместе с изображением +SAVEDLG_TIFFFILTER;Файлы TIFF +SAVEDLG_TIFFUNCOMPRESSED;Несжатый 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_CHROMATABERR_LABEL;Хроматические аберрации +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_GTEPASSPORT;Биометрический пасспорт +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_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;(Экспериментально) Автоматическая коррекция дисторсию на некоторых камерах (M4/3, некоторые компактные камеры и т.д.) +TP_DISTORTION_LABEL;Дисторсия +TP_EPD_EDGESTOPPING;Определение контуров +TP_EPD_LABEL;Тональная компрессия +TP_EPD_REWEIGHTINGITERATES;Перевзвешивание проходов +TP_EPD_SCALE;Масштаб +TP_EPD_STRENGTH;Интенсивность +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_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_CURVEEDITOR;Тоновая кривая +TP_EXPOSURE_EXPCOMP;Компенсация экспозиции +TP_EXPOSURE_LABEL;Экспозиция +TP_EXPOSURE_SATURATION;Насыщенность +TP_EXPO_AFTER; После интерпояции (перед RGB-преобразованием) +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_HSVEQUALIZER1;Красный +TP_HSVEQUALIZER2;Жёлтый +TP_HSVEQUALIZER3;Лимонный +TP_HSVEQUALIZER4;Зелёный +TP_HSVEQUALIZER5;Голубой +TP_HSVEQUALIZER6;Синий +TP_HSVEQUALIZER7;Фиолетовый +TP_HSVEQUALIZER8;Пурпурный +TP_HSVEQUALIZER_CHANNEL;Каналы HSV +TP_HSVEQUALIZER_HUE;H +TP_HSVEQUALIZER_LABEL;Эквалайзер HSV +TP_HSVEQUALIZER_NEUTRAL;Нейтральный +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_GAMMABEFOREINPUT;Применять гамму для профиля +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_OUTPUTDLGLABEL;Выберите выходной ICC профиль... +TP_ICM_OUTPUTPROFILE;Выходной профиль +TP_ICM_PREFERREDPROFILE;Предпочитаемый профиль DCP +TP_ICM_PREFERREDPROFILE_1;Дневное +TP_ICM_PREFERREDPROFILE_2;Вольфрамовое +TP_ICM_PREFERREDPROFILE_3;Флюоресцентное +TP_ICM_PREFERREDPROFILE_4;Вспышка +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;Кривые Lab +TP_LABCURVE_SATLIMIT;Ограничение насыщенности +TP_LABCURVE_SATURATION;Насыщенность +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_LUMACURVE_BLACKLEVEL;Уровень чёрного +TP_LUMACURVE_BRIGHTNESS;Яркость +TP_LUMACURVE_COMPRHIGHLIGHTS;Сжатие светов +TP_LUMACURVE_COMPRSHADOWS;Сжатие теней +TP_LUMACURVE_CONTRAST;Контраст +TP_LUMACURVE_CURVEEDITOR;Тоновая кривая +TP_LUMACURVE_LABEL;Кривая яркости +TP_LUMADENOISE_EDGETOLERANCE;Устойчивость к границам контуров +TP_LUMADENOISE_LABEL;Удаление шума +TP_LUMADENOISE_RADIUS;радиус +TP_NEUTRAL;Нейтральный +TP_NEUTRAL_TIP;Сбросить настройки выдержки на средние значения +TP_PERSPECTIVE_HORIZONTAL;Горизонтальная +TP_PERSPECTIVE_LABEL;Перспектива +TP_PERSPECTIVE_VERTICAL;Вертикальная +TP_PREPROCESS_GREENEQUIL;Выравнивание зелёного +TP_PREPROCESS_HOTDEADPIXFILT;Применить фильтр засвеченных/битых пикселей +TP_PREPROCESS_HOTDEADPIXTHRESH;Уровень засвеченных/битых пикселей +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_DOWNSCALEB;Уменьшение (качественно) +TP_RESIZE_DOWNSCALEF;Уменьшение (быстро) +TP_RESIZE_FITBOX;Ограничивающей рамке +TP_RESIZE_FULLIMAGE;Полному изображению +TP_RESIZE_FULLSIZE;Размер изображения: +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_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_VIBRANCE_AVOIDCOLORSHIFT;Избегать сдвига цветов +TP_VIBRANCE_LABEL;Резонанс +TP_VIBRANCE_PASTELS;Пастельные тона +TP_VIBRANCE_PASTSATTOG;Связать пастельные и насыщенные тона +TP_VIBRANCE_PROTECTSKINS;Сохранить оттенки кожи +TP_VIBRANCE_PSTHRESHOLD;Уровень патсельных/насыщенных тонов +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;Вольфрамовый +ZOOMBAR_DETAIL;Увеличение +ZOOMBAR_HUGE;Максимальное +ZOOMBAR_LARGE;Большое +ZOOMBAR_NORMAL;Среднее +ZOOMBAR_PREVIEW;Предпросмотр +ZOOMBAR_SCALE;Масштаб +ZOOMBAR_SMALL;Минимальное +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;Новое окно детального просмотра +ZOOMPANEL_ZOOM100;Масштаб 100% 1 +ZOOMPANEL_ZOOMFITSCREEN;По размерам окна F +ZOOMPANEL_ZOOMIN;Приблизить + +ZOOMPANEL_ZOOMOUT;Удалить - +#00 Russian +#01 23.12.2007 +#02 ArtDen +#03 20.07.2008: Denis Artemov +#04 16.02.2009: Kvark +#05 26.02.2010: Sergey Smirnov AKA smiserg +#06 01.11.2010: Ilia Popov +#07 17.07.2012: Roman Milanskij + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +GENERAL_WARNING;Внимание +HISTOGRAM_TOOLTIP_FULL;Переключить полную или отмасштабированную гистограмму +HISTORY_MSG_167;Ч/Б тонирование +HISTORY_MSG_168;'Цц' кривая +HISTORY_MSG_169;'Цо' кривая +HISTORY_MSG_170;Резонанс - кривая +MAIN_TOOLTIP_BACKCOLOR0;Фоновый цвет предпросмотра: Как в теме\nГорячая клавиша: 8 +MAIN_TOOLTIP_BACKCOLOR1;Фоновый цвет предпросмотра: Черный\nГорячая клавиша: 9 +MAIN_TOOLTIP_BACKCOLOR2;Фоновый цвет предпросмотра: Белый\nГорячая клавиша: 0 +NAVIGATOR_XY_FULL;Ширина = %1, Высота = %2 +PROGRESSBAR_PROCESSING_PROFILESAVED;Профиль обработки сохранен +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_WARNFILENAME;Файл будет наименован +SHCSELECTOR_TOOLTIP;Нажмите правую кнопку мыши для сброса\nпозиции этих трех ползунков +THRESHOLDSELECTOR_BL;Нижний левый +THRESHOLDSELECTOR_BR;Нижний правый +THRESHOLDSELECTOR_B;Низ +THRESHOLDSELECTOR_HINT;Зажмите клавишу Shift для перемещения отдельных контрольных точек. +THRESHOLDSELECTOR_TL;Верхний левый +THRESHOLDSELECTOR_TR;Верхний правый +THRESHOLDSELECTOR_T;Верх +TP_CROP_GTFRAME;Рамка +TP_LABCURVE_AVOIDCOLORSHIFT;Избегать сдвига цветов +TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Умещать цвета в гамму рабочего цветового пространства и применять коррекцию Манселла +TP_LABCURVE_BWTONING;Ч/Б тонирование +TP_LABCURVE_BWTONING_TIP;Со включенной опцией Ч/Б тонирование, цветность Lab, кривые Цц и Цо не используются.\nТонирование выполняется с помощью кривых a и b +TP_LABCURVE_CHROMATICITY;Цветность +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_RSTPROTECTION;Защита красных тонов и оттенков кожи +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_PSTHRESHOLD_SATTHRESH;Порог насыщенности +TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;Вертикальная ось обозначает пастельные тона внизу и насыщенные вверху.\nГоризонтальная ось представляет диапазон насыщенности. +TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Условие перехода пастельных/насыщенных diff --git a/rtdata/languages/Serbian (Cyrilic Characters) b/rtdata/languages/Serbian (Cyrilic Characters) new file mode 100644 index 000000000..d8c1459b4 --- /dev/null +++ b/rtdata/languages/Serbian (Cyrilic Characters) @@ -0,0 +1,1227 @@ +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_DIALOGLABEL;Exif филтер +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_ARRANGEMENTHINT;Размењује вертикални и хоризонтални распоред умањених приказа +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_EXIFFILTERAPPLYHINT;Укључује/искључује exif филтер у разгледачу датотека +FILEBROWSER_EXIFFILTERAPPLY;Примени +FILEBROWSER_EXIFFILTERLABEL;Exif филтер +FILEBROWSER_EXIFFILTERSETTINGSHINT;Мења подешавања exif филтера +FILEBROWSER_EXIFFILTERSETTINGS;Подеси +FILEBROWSER_FLATFIELD;Равно поље +FILEBROWSER_MOVETODARKFDIR;Пребаци у фасциклу са тамним кадровима +FILEBROWSER_MOVETOFLATFIELDDIR;Премести у фасцикли са равним пољима +FILEBROWSER_NEW_NAME;Ново име: +FILEBROWSER_PARTIALPASTEPROFILE;Делимично убаци +FILEBROWSER_PASTEPROFILE;Убаци профил +FILEBROWSER_POPUPCANCELJOB;Откажи задатак +FILEBROWSER_POPUPCOLORLABEL0;Ознака: Ништа +FILEBROWSER_POPUPCOLORLABEL1;Ознака: Црвена +FILEBROWSER_POPUPCOLORLABEL2;Ознака: Жута +FILEBROWSER_POPUPCOLORLABEL3;Ознака: Зелена +FILEBROWSER_POPUPCOLORLABEL4;Ознака: Плава +FILEBROWSER_POPUPCOLORLABEL5;Ознака: Љубичаста +FILEBROWSER_POPUPCOLORLABEL;Обојена ознака +FILEBROWSER_POPUPCOPYTO;Умножи у... +FILEBROWSER_POPUPFILEOPERATIONS;Датотека +FILEBROWSER_POPUPMOVEEND;Премести на крај заказаних +FILEBROWSER_POPUPMOVEHEAD;Премести на почетак заказаних +FILEBROWSER_POPUPMOVETO;Премести у... +FILEBROWSER_POPUPOPEN;Отвори +FILEBROWSER_POPUPPROCESS;Закажи за обраду +FILEBROWSER_POPUPPROFILEOPERATIONS;Профил +FILEBROWSER_POPUPRANK1;Оцени са 1 +FILEBROWSER_POPUPRANK2;Оцени са 2 +FILEBROWSER_POPUPRANK3;Оцени са 3 +FILEBROWSER_POPUPRANK4;Оцени са 4 +FILEBROWSER_POPUPRANK5;Оцени са 5 +FILEBROWSER_POPUPREMOVEINCLPROC;Уклони из система датотека и заказаног +FILEBROWSER_POPUPREMOVESUBMENU;Уклони +FILEBROWSER_POPUPREMOVE;Уклони из система датотека +FILEBROWSER_POPUPRENAME;Преименуј +FILEBROWSER_POPUPSELECTALL;Изабери све +FILEBROWSER_POPUPTRASH;Премести у смеће +FILEBROWSER_POPUPUNRANK;Уклони оцену +FILEBROWSER_POPUPUNTRASH;Уклони из смећа +FILEBROWSER_PROCESSINGSETTINGSHINT;Поставља формат датотеке и излазни директоријум +FILEBROWSER_PROCESSINGSETTINGS;Подешавања +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_SHOWQUEUEHINT;Приказује слике заказане за обраду +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-` +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_HIGH_QUALITY;Висок квалитет +GENERAL_LANDSCAPE;Положено +GENERAL_LOAD;Учитај +GENERAL_NA;нема +GENERAL_NONE;Ништа +GENERAL_NO;Не +GENERAL_OK;У реду +GENERAL_PORTRAIT;Усправно +GENERAL_SAVE;Сачувај +GENERAL_UNCHANGED;(неизмењено) +GENERAL_YES;Да +HISTOGRAM_BUTTON_BAR;РГБ +HISTOGRAM_BUTTON_B;П +HISTOGRAM_BUTTON_G;З +HISTOGRAM_BUTTON_L;С +HISTOGRAM_BUTTON_RAW;Raw +HISTOGRAM_BUTTON_R;Ц +HISTOGRAM_LABEL;Хистограм +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_NEWSNAPSHOTAS;Као... +HISTORY_NEWSNAPSHOT;Додај +HISTORY_NEWSSDIALOGLABEL;Назив снимка: +HISTORY_NEWSSDIALOGTITLE;Додај нови снимак +HISTORY_SETTO;Посави на +HISTORY_SNAPSHOTS;Снимак +HISTORY_SNAPSHOT;Снимак +ICMPANEL_FILEDLGFILTERANY;Све датотеке +ICMPANEL_FILEDLGFILTERICM;ИЦЦ профили +ICMPANEL_GAMMABEFOREINPUT;Гама профили +ICMPANEL_INPUTCAMERA;Подразумевано из апарата +ICMPANEL_INPUTCUSTOM;Произвољно +ICMPANEL_INPUTDLGLABEL;Изаберите улазни профил... +ICMPANEL_INPUTEMBEDDED;Користи уметнути уколико је могуће +ICMPANEL_INPUTPROFILE;Улазни профил +ICMPANEL_NOICM;No ICM: sRGB излаз +ICMPANEL_OUTPUTDLGLABEL;Изаберите излазни ИЦЦ профил... +ICMPANEL_OUTPUTPROFILE;Излазни профил +ICMPANEL_SAVEREFERENCE;Сачувај слику као референцу за профил +ICMPANEL_WORKINGPROFILE;Радни профил +IMAGEAREA_DETAILVIEW;Приказ детаља +IPTCPANEL_AUTHORHINT;Име аутора, нпр. писац, фотограф или графички дизајнер (један по реду). +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_EXIT;Изађи +MAIN_BUTTON_FULLSCREEN;Цео екран +MAIN_BUTTON_PREFERENCES;Поставке +MAIN_BUTTON_PUTTOQUEUE;Закажи +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Додаје тренутну слику у заказане Ctrl+Q +MAIN_BUTTON_QUEUE;Закажи +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_ERRORDURINGIMAGESAVING;Грешка прилоком чувања слике +MAIN_MSG_EXITJOBSINQUEUEINFO;Заказане слике неће бити обрађене. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Да ли заиста желите да изађете? Неке слике су још увек заказане за обраду. +MAIN_MSG_JOBSINQUEUE;слика(е) у заказаним. +MAIN_MSG_NAVIGATOR;Навигатор +MAIN_MSG_PLACES;Места +MAIN_MSG_QOVERWRITE;Да ли желите да препишете? +MAIN_TAB_BASIC;Основно +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_ICM;ИЦМ +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_TOGGLE_BEFORE_AFTER;Б|А +MAIN_TOOLTIP_HIDEFP;Приказује/сакрива доњу површ, директоријуме и разгледач датотека (пречица: Ф) +MAIN_TOOLTIP_HIDEHP;Приказује/сакрива леву површ, заједно са историјатом (пречица: Х) +MAIN_TOOLTIP_INDCLIPPEDH;Приказује исечене светле делове +MAIN_TOOLTIP_INDCLIPPEDS;Приказује исечене тамне делове +MAIN_TOOLTIP_PREFERENCES;Мења поставке програма +MAIN_TOOLTIP_QINFO;Основни подаци о слици И +MAIN_TOOLTIP_SAVEAS;Чува слику у изабрану фасциклу +MAIN_TOOLTIP_SAVE;Чува слику у подразумевану фасциклу +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_COLORBOOST;Појачање боја +PARTIALPASTE_COLORDENOISE;Уклањање колорног шума +PARTIALPASTE_COLORGROUP;Подешавање боја +PARTIALPASTE_COLORMIXER;Мешање боја +PARTIALPASTE_COLORSHIFT;Померај боја +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_HLRECONSTRUCTION;Извлачење преосветљених делова +PARTIALPASTE_HLRECOVERYAMOUNT;Количина извлачења преосветљеног +PARTIALPASTE_HLRECOVERYTHRESHOLD;Праг извлачења преосветљеног +PARTIALPASTE_HLRECOVERY;Чуање светлих делова +PARTIALPASTE_HSVEQUALIZER;Уједначење ХСВ +PARTIALPASTE_ICMSETTINGS;ИЦМ подешавања +PARTIALPASTE_IMPULSEDENOISE;Импулсно уклањање шума +PARTIALPASTE_IPTCINFO;ИПТЦ подави +PARTIALPASTE_LABCURVE;Лаб крива +PARTIALPASTE_LENSGROUP;Подешавања објектива +PARTIALPASTE_LUMACURVE;Крива луминасе +PARTIALPASTE_LUMADENOISE;Уклањање светлосног шума +PARTIALPASTE_LUMINANCEGROUP;Подешавања луминансе +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_WAVELETEQUALIZER;Таласно уједначавање +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_CACHESTRAT1;Бржи рад уз употребу више меморије +PREFERENCES_CACHESTRAT2;Мала заузетост меморије, уз спорији рад +PREFERENCES_CACHESTRAT;Остава +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_DEMOSAICINGALGO;Алгоритам за склапање +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_HINT;Савет +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_LIVETHUMBNAILS;„Живи“ прикази (спорије) +PREFERENCES_MENUGROUPFILEOPERATIONS;Групиши радње над датотекама +PREFERENCES_MENUGROUPLABEL;Групиши обележавање +PREFERENCES_MENUGROUPPROFILEOPERATIONS;Групиши радње са профилима +PREFERENCES_MENUGROUPRANK;Групиши оцењивање +PREFERENCES_MENUOPTIONS;Опције менија +PREFERENCES_METADATA;Метаподаци +PREFERENCES_MONITORICC;Профил монитора +PREFERENCES_MULTITABDUALMON;Режим у више листова, на другом монитору +PREFERENCES_MULTITAB;Режим у више листова +PREFERENCES_OUTDIRFOLDERHINT;Ставља сачуване слике у +PREFERENCES_OUTDIRFOLDER;Сачувај у фасциклу +PREFERENCES_OUTDIRHINT;Можете да задате следеће скраћенице за форматирање:\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_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_SELECTICCDIRDLG;Изаберите директоријум са ИЦЦ профилима... +PREFERENCES_SELECTLANG;Језик +PREFERENCES_SELECTMONITORPROFDLG;Изаберите ИЦЦ профил екрана... +PREFERENCES_SELECTTHEME;Тема +PREFERENCES_SET;Постави +PREFERENCES_SHOWBASICEXIF;Прикажи основне Exif податке +PREFERENCES_SHOWDATETIME;Прикажи датум и време +PREFERENCES_SHOWONLYRAW;Прикажи само RAW датотеке +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_OUTPUT;Опције на излазу +PREFERENCES_TAB_SOUND;Звуци +PREFERENCES_THUMBSIZE;Величина умањеног приказа +PREFERENCES_TP_VSCROLLBAR;Сакриј клизаче у области са алаткама +PREFERENCES_TUNNELMETADATA;Копирај неизмењене IPTC/XMP (када је слика означена другим програмом) +PREFERENCES_USESYSTEMTHEME; Користи системску тему +PREFERENCES_WORKFLOW;Ток обраде +PROFILEPANEL_FILEDLGFILTERANY;Све датотеке +PROFILEPANEL_FILEDLGFILTERPP;Профили за обраду +PROFILEPANEL_LABEL;Профили обраде +PROFILEPANEL_LOADDLGLABEL;Учитај профил за обраду... +PROFILEPANEL_PCUSTOM;Произвољно +PROFILEPANEL_PFILE;Из датотеке +PROFILEPANEL_PLASTPHOTO;Из последње слике +PROFILEPANEL_PLASTSAVED;Од последњег чувања +PROFILEPANEL_PROFILE;Профил +PROFILEPANEL_SAVEDLGLABEL;Чува параметре за обраду... +PROFILEPANEL_TOOLTIPCOPY;Копира тренутни профил у оставу +PROFILEPANEL_TOOLTIPLOAD;Учитава профил из датотеке +PROFILEPANEL_TOOLTIPPASTE; Учитава профил из +PROFILEPANEL_TOOLTIPSAVE;Чува тренутни профил +PROGRESSBAR_BADPIXELS;Лоши пиксели... +PROGRESSBAR_CACORRECTION;Хроматске аберације... +PROGRESSBAR_DARKFRAME;Тамни кадар... +PROGRESSBAR_DECODING;Учитавам податке из raw датотеке... +PROGRESSBAR_DEMOSAICING;Склапам слику... +PROGRESSBAR_GREENEQUIL;Уравнотежавам зелену... +PROGRESSBAR_LINEDENOISE;Линијки шум... +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_FOCALLENGTH;Жижна дужина +QINFO_ISO;ИСО +QINFO_LENS;Објектив +QINFO_NOEXIF;Нису доступни Exif подаци. +SAVEDLG_AUTOSUFFIX;Сам додај суфикс уколико датотека већ постоји +SAVEDLG_FILEFORMAT;Формат датотеке +SAVEDLG_JPEGQUAL;JPEG квалитет +SAVEDLG_JPGFILTER;JPEG датотеке +SAVEDLG_PNGCOMPR;PNG паковање +SAVEDLG_PNGFILTER;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_NEUTRAL;Неутрално +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_OUTPUTDLGLABEL;Изаберите излазни ИЦЦ профил... +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_LUMADENOISE_EDGETOLERANCE;Толеранција ивице +TP_LUMADENOISE_LABEL;Уклањање светлосног шума +TP_LUMADENOISE_RADIUS;Полупречник +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_FULLSIZE;Стварна величина слике: +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;Температура +ZOOMBAR_DETAIL;Детаљи +ZOOMBAR_HUGE;Највеће +ZOOMBAR_LARGE;Велико +ZOOMBAR_NORMAL;Нормално +ZOOMBAR_PREVIEW;Преглед +ZOOMBAR_SCALE;Умањено +ZOOMBAR_SMALL;Мало +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;Отвара нови прозор са детаљима +ZOOMPANEL_ZOOM100;Повећава преглед на 100% 1 +ZOOMPANEL_ZOOMFITSCREEN;Уклапа слику у величину прозора Ф +ZOOMPANEL_ZOOMIN;Увећава приказ слике + +ZOOMPANEL_ZOOMOUT;Умањује приказ слике - + +#00 Serbian (Cyrilic) +#01 by gpopac 2010-11-16 +# Serbian translation +HISTOGRAM_BUTTON_B;П + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!ABOUT_TAB_RELEASENOTES;Release Notes +!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_SHARPENEDGE;Bypass Edge Sharpening +!EXPORT_BYPASS_SHARPENING;Bypass Sharpening +!EXPORT_BYPASS_SHARPENMICRO;Bypass Microcontrast +!EXPORT_BYPASS_SH_HQ;Bypass Shadow/Highlights (High Quality) +!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_EXTPROGMENU;Open with +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!FILEBROWSER_POPUPPROCESSFAST;Put to Queue (Fast export) +!GENERAL_WARNING;Warning +!HISTOGRAM_TOOLTIP_FULL;Toggle full or scaled histogram +!HISTORY_MSG_151;Vibrance +!HISTORY_MSG_152;Vibrance - Pastel tones +!HISTORY_MSG_153;Vibrance - Saturated tones +!HISTORY_MSG_154;Vibrance - Protect skin tones +!HISTORY_MSG_155;Vibrance - Avoid color drift +!HISTORY_MSG_156;Vibrance - Link pastel and saturated tones +!HISTORY_MSG_157;Vibrance - Pastel/Saturated threshold +!HISTORY_MSG_158;Strength +!HISTORY_MSG_159;Edge Stopping +!HISTORY_MSG_160;Scale +!HISTORY_MSG_161;Reweighting Iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_163;RGB Curves - R +!HISTORY_MSG_164;RGB Curves - G +!HISTORY_MSG_165;RGB Curves - B +!HISTORY_MSG_166;Neutral Levels +!HISTORY_MSG_167;B&W Toning +!HISTORY_MSG_168;'Cc' curve +!HISTORY_MSG_169;'Ch' curve +!HISTORY_MSG_170;Vibrance - Curve +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue processed first. +!MAIN_TAB_EXPORT; Export +!MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 8 +!MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 0 +!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_EPD;Tone Mapping +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_RGBCURVES;RGB curves +!PARTIALPASTE_VIBRANCE;Vibrance +!PREFERENCES_MENUGROUPEXTPROGS;Group "Open with" +!PREFERENCES_SHOWEXPOSURECOMPENSATION;Append exposure compensation +!PREFERENCES_TP_LABEL;Tool panel: +!PREFERENCES_TP_USEICONORTEXT;Use tab icons instead of text +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_SAVEPPASTE;Parameters to save +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing Profile Saved +!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\nthe 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_CROP_GTEPASSPORT;Biometric Passport +!TP_CROP_GTFRAME;Frame +!TP_EPD_EDGESTOPPING;Edge stopping +!TP_EPD_LABEL;Tone Mapping +!TP_EPD_REWEIGHTINGITERATES;Reweighting iterates +!TP_EPD_SCALE;Scale +!TP_EPD_STRENGTH;Strength +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggle execution of Auto Levels to automatically set parameter values based on image analysis +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in auto levels operation +!TP_GAMMA_CURV;gamma +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover blown highlights when using LUT based ICC profiles +!TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profile. These profiles are more precise than simpler matrix ones. Available for some 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_PREFERREDPROFILE;Preferred DCP profile +!TP_ICM_PREFERREDPROFILE_1;Daylight +!TP_ICM_PREFERREDPROFILE_2;Tungsten +!TP_ICM_PREFERREDPROFILE_3;Fluorescent +!TP_ICM_PREFERREDPROFILE_4;Flash +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid Color Shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space\nand apply Munsell correction +!TP_LABCURVE_BWTONING;B&W Toning +!TP_LABCURVE_BWTONING_TIP;With B&W Toning option enabled, the Lab Chromaticity, Cc and Ch curves are not in effect.\nToning can be achieved using the a and b curves +!TP_LABCURVE_CHROMATICITY;Chromaticity +!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 the Chromaticity +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to the Hue +!TP_LABCURVE_RSTPROTECTION;Red and Skin Tones Protection +!TP_LENSPROFILE_FILEDLGFILTERLCP;Lens correction files +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;Use CA correction +!TP_LENSPROFILE_USEDIST;Use distortion correction +!TP_LENSPROFILE_USEVIGN;Use vignette correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset exposure controls to neutral values +!TP_PREPROCESS_HOTDEADPIXTHRESH;Hot/dead pixel detection threshold +!TP_RGBCURVES_BLUE;B +!TP_RGBCURVES_CHANNEL;Channel +!TP_RGBCURVES_GREEN;G +!TP_RGBCURVES_LABEL;RGB Curves +!TP_RGBCURVES_RED;R +!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 the Hue +!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_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 diff --git a/rtdata/languages/Serbian (Latin Characters) b/rtdata/languages/Serbian (Latin Characters) new file mode 100644 index 000000000..1ede8b56a --- /dev/null +++ b/rtdata/languages/Serbian (Latin Characters) @@ -0,0 +1,1227 @@ +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_DIALOGLABEL;Exif filter +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_ARRANGEMENTHINT;Razmenjuje vertikalni i horizontalni raspored umanjenih prikaza +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_EXIFFILTERAPPLYHINT;Uključuje/isključuje exif filter u razgledaču datoteka +FILEBROWSER_EXIFFILTERAPPLY;Primeni +FILEBROWSER_EXIFFILTERLABEL;Exif filter +FILEBROWSER_EXIFFILTERSETTINGSHINT;Menja podešavanja exif filtera +FILEBROWSER_EXIFFILTERSETTINGS;Podesi +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_POPUPCOLORLABEL0;Oznaka: Ništa +FILEBROWSER_POPUPCOLORLABEL1;Oznaka: Crvena +FILEBROWSER_POPUPCOLORLABEL2;Oznaka: Žuta +FILEBROWSER_POPUPCOLORLABEL3;Oznaka: Zelena +FILEBROWSER_POPUPCOLORLABEL4;Oznaka: Plava +FILEBROWSER_POPUPCOLORLABEL5;Oznaka: Ljubičasta +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_POPUPRANK1;Oceni sa 1 +FILEBROWSER_POPUPRANK2;Oceni sa 2 +FILEBROWSER_POPUPRANK3;Oceni sa 3 +FILEBROWSER_POPUPRANK4;Oceni sa 4 +FILEBROWSER_POPUPRANK5;Oceni sa 5 +FILEBROWSER_POPUPREMOVEINCLPROC;Ukloni iz sistema datoteka i zakazanog +FILEBROWSER_POPUPREMOVESUBMENU;Ukloni +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_PROCESSINGSETTINGSHINT;Postavlja format datoteke i izlazni direktorijum +FILEBROWSER_PROCESSINGSETTINGS;Podešavanja +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_SHOWQUEUEHINT;Prikazuje slike zakazane za obradu +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-` +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_HIGH_QUALITY;Visok kvalitet +GENERAL_LANDSCAPE;Položeno +GENERAL_LOAD;Učitaj +GENERAL_NA;nema +GENERAL_NONE;Ništa +GENERAL_NO;Ne +GENERAL_OK;U redu +GENERAL_PORTRAIT;Uspravno +GENERAL_SAVE;Sačuvaj +GENERAL_UNCHANGED;(neizmenjeno) +GENERAL_YES;Da +HISTOGRAM_BUTTON_BAR;RGB +HISTOGRAM_BUTTON_B;P +HISTOGRAM_BUTTON_G;Z +HISTOGRAM_BUTTON_L;S +HISTOGRAM_BUTTON_RAW;Raw +HISTOGRAM_BUTTON_R;C +HISTOGRAM_LABEL;Histogram +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_NEWSNAPSHOTAS;Kao... +HISTORY_NEWSNAPSHOT;Dodaj +HISTORY_NEWSSDIALOGLABEL;Naziv snimka: +HISTORY_NEWSSDIALOGTITLE;Dodaj novi snimak +HISTORY_SETTO;Posavi na +HISTORY_SNAPSHOTS;Snimak +HISTORY_SNAPSHOT;Snimak +ICMPANEL_FILEDLGFILTERANY;Sve datoteke +ICMPANEL_FILEDLGFILTERICM;ICC profili +ICMPANEL_GAMMABEFOREINPUT;Gama profili +ICMPANEL_INPUTCAMERA;Podrazumevano iz aparata +ICMPANEL_INPUTCUSTOM;Proizvoljno +ICMPANEL_INPUTDLGLABEL;Izaberite ulazni profil... +ICMPANEL_INPUTEMBEDDED;Koristi umetnuti ukoliko je moguće +ICMPANEL_INPUTPROFILE;Ulazni profil +ICMPANEL_NOICM;No ICM: sRGB izlaz +ICMPANEL_OUTPUTDLGLABEL;Izaberite izlazni ICC profil... +ICMPANEL_OUTPUTPROFILE;Izlazni profil +ICMPANEL_SAVEREFERENCE;Sačuvaj sliku kao referencu za profil +ICMPANEL_WORKINGPROFILE;Radni profil +IMAGEAREA_DETAILVIEW;Prikaz detalja +IPTCPANEL_AUTHORHINT;Ime autora, npr. pisac, fotograf ili grafički dizajner (jedan po redu). +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_EXIT;Izađi +MAIN_BUTTON_FULLSCREEN;Ceo ekran +MAIN_BUTTON_PREFERENCES;Postavke +MAIN_BUTTON_PUTTOQUEUE;Zakaži +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Dodaje trenutnu sliku u zakazane Ctrl+Q +MAIN_BUTTON_QUEUE;Zakaži +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_ERRORDURINGIMAGESAVING;Greška prilokom čuvanja slike +MAIN_MSG_EXITJOBSINQUEUEINFO;Zakazane slike neće biti obrađene. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Da li zaista želite da izađete? Neke slike su još uvek zakazane za obradu. +MAIN_MSG_JOBSINQUEUE;slika(e) u zakazanim. +MAIN_MSG_NAVIGATOR;Navigator +MAIN_MSG_PLACES;Mesta +MAIN_MSG_QOVERWRITE;Da li želite da prepišete? +MAIN_TAB_BASIC;Osnovno +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_ICM;ICM +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_TOGGLE_BEFORE_AFTER;B|A +MAIN_TOOLTIP_HIDEFP;Prikazuje/sakriva donju površ, direktorijume i razgledač datoteka (prečica: F) +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_PREFERENCES;Menja postavke programa +MAIN_TOOLTIP_QINFO;Osnovni podaci o slici I +MAIN_TOOLTIP_SAVEAS;Čuva sliku u izabranu fasciklu +MAIN_TOOLTIP_SAVE;Čuva sliku u podrazumevanu fasciklu +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_COLORBOOST;Pojačanje boja +PARTIALPASTE_COLORDENOISE;Uklanjanje kolornog šuma +PARTIALPASTE_COLORGROUP;Podešavanje boja +PARTIALPASTE_COLORMIXER;Mešanje boja +PARTIALPASTE_COLORSHIFT;Pomeraj 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_HLRECONSTRUCTION;Izvlačenje preosvetljenih delova +PARTIALPASTE_HLRECOVERYAMOUNT;Količina izvlačenja preosvetljenog +PARTIALPASTE_HLRECOVERYTHRESHOLD;Prag izvlačenja preosvetljenog +PARTIALPASTE_HLRECOVERY;Čuanje svetlih delova +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_LUMADENOISE;Uklanjanje svetlosnog šuma +PARTIALPASTE_LUMINANCEGROUP;Podešavanja luminanse +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_WAVELETEQUALIZER;Talasno ujednačavanje +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_CACHESTRAT1;Brži rad uz upotrebu više memorije +PREFERENCES_CACHESTRAT2;Mala zauzetost memorije, uz sporiji rad +PREFERENCES_CACHESTRAT;Ostava +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_DEMOSAICINGALGO;Algoritam za sklapanje +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_HINT;Savet +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_LIVETHUMBNAILS;„Živi“ prikazi (sporije) +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_OUTDIRHINT;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_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_SELECTICCDIRDLG;Izaberite direktorijum sa ICC profilima... +PREFERENCES_SELECTLANG;Jezik +PREFERENCES_SELECTMONITORPROFDLG;Izaberite ICC profil ekrana... +PREFERENCES_SELECTTHEME;Tema +PREFERENCES_SET;Postavi +PREFERENCES_SHOWBASICEXIF;Prikaži osnovne Exif podatke +PREFERENCES_SHOWDATETIME;Prikaži datum i vreme +PREFERENCES_SHOWONLYRAW;Prikaži samo RAW datoteke +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_OUTPUT;Opcije na izlazu +PREFERENCES_TAB_SOUND;Zvuci +PREFERENCES_THUMBSIZE;Veličina umanjenog prikaza +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_PLASTPHOTO;Iz poslednje slike +PROFILEPANEL_PLASTSAVED;Od poslednjeg čuvanja +PROFILEPANEL_PROFILE;Profil +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_BADPIXELS;Loši pikseli... +PROGRESSBAR_CACORRECTION;Hromatske aberacije... +PROGRESSBAR_DARKFRAME;Tamni kadar... +PROGRESSBAR_DECODING;Učitavam podatke iz raw datoteke... +PROGRESSBAR_DEMOSAICING;Sklapam sliku... +PROGRESSBAR_GREENEQUIL;Uravnotežavam zelenu... +PROGRESSBAR_LINEDENOISE;Linijki šum... +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_FOCALLENGTH;Žižna dužina +QINFO_ISO;ISO +QINFO_LENS;Objektiv +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_PNGFILTER;PNG datoteke +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_NEUTRAL;Neutralno +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_OUTPUTDLGLABEL;Izaberite izlazni ICC profil... +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_LUMADENOISE_EDGETOLERANCE;Tolerancija ivice +TP_LUMADENOISE_LABEL;Uklanjanje svetlosnog šuma +TP_LUMADENOISE_RADIUS;Poluprečnik +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_FULLSIZE;Stvarna veličina slike: +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 +ZOOMBAR_DETAIL;Detalji +ZOOMBAR_HUGE;Najveće +ZOOMBAR_LARGE;Veliko +ZOOMBAR_NORMAL;Normalno +ZOOMBAR_PREVIEW;Pregled +ZOOMBAR_SCALE;Umanjeno +ZOOMBAR_SMALL;Malo +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;Otvara novi prozor sa detaljima +ZOOMPANEL_ZOOM100;Povećava pregled na 100% 1 +ZOOMPANEL_ZOOMFITSCREEN;Uklapa sliku u veličinu prozora F +ZOOMPANEL_ZOOMIN;Uvećava prikaz slike + +ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - + +#00 Serbian (Cyrilic) +#01 by gpopac 2010-11-16 +# Serbian translation +HISTOGRAM_BUTTON_B;P + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!ABOUT_TAB_RELEASENOTES;Release Notes +!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_SHARPENEDGE;Bypass Edge Sharpening +!EXPORT_BYPASS_SHARPENING;Bypass Sharpening +!EXPORT_BYPASS_SHARPENMICRO;Bypass Microcontrast +!EXPORT_BYPASS_SH_HQ;Bypass Shadow/Highlights (High Quality) +!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_EXTPROGMENU;Open with +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!FILEBROWSER_POPUPPROCESSFAST;Put to Queue (Fast export) +!GENERAL_WARNING;Warning +!HISTOGRAM_TOOLTIP_FULL;Toggle full or scaled histogram +!HISTORY_MSG_151;Vibrance +!HISTORY_MSG_152;Vibrance - Pastel tones +!HISTORY_MSG_153;Vibrance - Saturated tones +!HISTORY_MSG_154;Vibrance - Protect skin tones +!HISTORY_MSG_155;Vibrance - Avoid color drift +!HISTORY_MSG_156;Vibrance - Link pastel and saturated tones +!HISTORY_MSG_157;Vibrance - Pastel/Saturated threshold +!HISTORY_MSG_158;Strength +!HISTORY_MSG_159;Edge Stopping +!HISTORY_MSG_160;Scale +!HISTORY_MSG_161;Reweighting Iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_163;RGB Curves - R +!HISTORY_MSG_164;RGB Curves - G +!HISTORY_MSG_165;RGB Curves - B +!HISTORY_MSG_166;Neutral Levels +!HISTORY_MSG_167;B&W Toning +!HISTORY_MSG_168;'Cc' curve +!HISTORY_MSG_169;'Ch' curve +!HISTORY_MSG_170;Vibrance - Curve +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue processed first. +!MAIN_TAB_EXPORT; Export +!MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 8 +!MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 0 +!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_EPD;Tone Mapping +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_RGBCURVES;RGB curves +!PARTIALPASTE_VIBRANCE;Vibrance +!PREFERENCES_MENUGROUPEXTPROGS;Group "Open with" +!PREFERENCES_SHOWEXPOSURECOMPENSATION;Append exposure compensation +!PREFERENCES_TP_LABEL;Tool panel: +!PREFERENCES_TP_USEICONORTEXT;Use tab icons instead of text +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_SAVEPPASTE;Parameters to save +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing Profile Saved +!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\nthe 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_CROP_GTEPASSPORT;Biometric Passport +!TP_CROP_GTFRAME;Frame +!TP_EPD_EDGESTOPPING;Edge stopping +!TP_EPD_LABEL;Tone Mapping +!TP_EPD_REWEIGHTINGITERATES;Reweighting iterates +!TP_EPD_SCALE;Scale +!TP_EPD_STRENGTH;Strength +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggle execution of Auto Levels to automatically set parameter values based on image analysis +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in auto levels operation +!TP_GAMMA_CURV;gamma +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover blown highlights when using LUT based ICC profiles +!TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profile. These profiles are more precise than simpler matrix ones. Available for some 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_PREFERREDPROFILE;Preferred DCP profile +!TP_ICM_PREFERREDPROFILE_1;Daylight +!TP_ICM_PREFERREDPROFILE_2;Tungsten +!TP_ICM_PREFERREDPROFILE_3;Fluorescent +!TP_ICM_PREFERREDPROFILE_4;Flash +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid Color Shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space\nand apply Munsell correction +!TP_LABCURVE_BWTONING;B&W Toning +!TP_LABCURVE_BWTONING_TIP;With B&W Toning option enabled, the Lab Chromaticity, Cc and Ch curves are not in effect.\nToning can be achieved using the a and b curves +!TP_LABCURVE_CHROMATICITY;Chromaticity +!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 the Chromaticity +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to the Hue +!TP_LABCURVE_RSTPROTECTION;Red and Skin Tones Protection +!TP_LENSPROFILE_FILEDLGFILTERLCP;Lens correction files +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;Use CA correction +!TP_LENSPROFILE_USEDIST;Use distortion correction +!TP_LENSPROFILE_USEVIGN;Use vignette correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset exposure controls to neutral values +!TP_PREPROCESS_HOTDEADPIXTHRESH;Hot/dead pixel detection threshold +!TP_RGBCURVES_BLUE;B +!TP_RGBCURVES_CHANNEL;Channel +!TP_RGBCURVES_GREEN;G +!TP_RGBCURVES_LABEL;RGB Curves +!TP_RGBCURVES_RED;R +!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 the Hue +!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_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 diff --git a/rtdata/languages/Slovak b/rtdata/languages/Slovak new file mode 100644 index 000000000..f95ff399a --- /dev/null +++ b/rtdata/languages/Slovak @@ -0,0 +1,1215 @@ +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_DIALOGLABEL;Exif filter +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_ARRANGEMENTHINT;Zmeniť medzi vertikálnym/horizontálnym zarovnaním zmenšenín +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_EXIFFILTERAPPLYHINT;Zapnúť/vypnúť EXIF filter prehliadača súborov +FILEBROWSER_EXIFFILTERAPPLY;Použiť +FILEBROWSER_EXIFFILTERLABEL;Exif Filter +FILEBROWSER_EXIFFILTERSETTINGSHINT;Zmeňte nastavenia EXIF filtra +FILEBROWSER_EXIFFILTERSETTINGS;Nastavenia +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_POPUPRANK1;Trieda 1 +FILEBROWSER_POPUPRANK2;Trieda 2 +FILEBROWSER_POPUPRANK3;Trieda 3 +FILEBROWSER_POPUPRANK4;Trieda 4 +FILEBROWSER_POPUPRANK5;Trieda 5 +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_PROCESSINGSETTINGSHINT;Nastaviť formát súborov a výstupný adresár +FILEBROWSER_PROCESSINGSETTINGS;Nastavenia +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_SHOWQUEUEHINT;Zobraziť obsah radu na spracovanie +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_HIGH_QUALITY;Vysoká kvalita +GENERAL_LANDSCAPE;Krajina +GENERAL_LOAD;Načítať +GENERAL_NA;n/a +GENERAL_NO;Nie +GENERAL_OK;OK +GENERAL_PORTRAIT;Portrét +GENERAL_SAVE;Uložiť +GENERAL_UNCHANGED;(Nezmenené) +GENERAL_YES;Áno +HISTOGRAM_BUTTON_B;B +HISTOGRAM_BUTTON_G;G +HISTOGRAM_BUTTON_L;L +HISTOGRAM_BUTTON_R;R +HISTOGRAM_LABEL;Histogram +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_NEWSNAPSHOTAS;Ako... +HISTORY_NEWSNAPSHOT;Nový Snímok +HISTORY_NEWSSDIALOGLABEL;Menovka snímku: +HISTORY_NEWSSDIALOGTITLE;Pridať nový snímok +HISTORY_SETTO;Nastaviť na +HISTORY_SNAPSHOTS;Snímky +HISTORY_SNAPSHOT;Snímok +ICMPANEL_FILEDLGFILTERANY;Všetky súbory +ICMPANEL_FILEDLGFILTERICM;Súbory ICC profilu +ICMPANEL_GAMMABEFOREINPUT;Profil aplikuje Gamu +ICMPANEL_INPUTCAMERA;Predvolený aparátu +ICMPANEL_INPUTCUSTOM;Vlastný +ICMPANEL_INPUTDLGLABEL;Vybrať vstupný ICC profil... +ICMPANEL_INPUTEMBEDDED;Použiť vstavaný, ak je to možné +ICMPANEL_INPUTPROFILE;Vstupný profil +ICMPANEL_NOICM;Bez správy farieb: sRGB výstup +ICMPANEL_OUTPUTDLGLABEL;Vybrať výstupný ICC profil... +ICMPANEL_OUTPUTPROFILE;Výstupný profil +ICMPANEL_SAVEREFERENCE;Uložiť referenčný obrázok pre tvorbu profilu +ICMPANEL_WORKINGPROFILE;Pracovný profil +IMAGEAREA_DETAILVIEW;Zobrazenie detailov +IPTCPANEL_AUTHORHINT;Meno tvorcu objektu, napr. pisateľa, fotografa alebo grafika (Meno autora). +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_EXIT;Ukončiť +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+Q +MAIN_BUTTON_QUEUE;Vložiť do radu +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_ERRORDURINGIMAGESAVING;Chyba pri ukladaní obrázka +MAIN_MSG_EXITJOBSINQUEUEINFO;Nespracované obrázky v rade budú pri ukončení programu stratené. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Ste si istí, že chcete ukončiť program? V rade sú nespracované obrázky. +MAIN_MSG_JOBSINQUEUE;Úlohy v rade +MAIN_MSG_NAVIGATOR;Navigátor +MAIN_MSG_PLACES;Miesta +MAIN_MSG_QOVERWRITE;Chcete ho prepísať? +MAIN_TAB_BASIC;Základné +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_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadáta +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;Transformácie +MAIN_TOGGLE_BEFORE_AFTER;B|A +MAIN_TOOLTIP_HIDEFP;Zobraziť/ukázať panel tlačidiel (prehliadač adresárov a súborov, shortcut key: F) +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_PREFERENCES;Nastaviť predvoľby +MAIN_TOOLTIP_QINFO;Rýchle informácie o obrázku +MAIN_TOOLTIP_SAVEAS;Uložiť obrázok do vybraného adresára +MAIN_TOOLTIP_SAVE;Uložiť obrázok do predvoleného adresára +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_COLORBOOST;Zosilnenie farieb +PARTIALPASTE_COLORDENOISE;Farebné odšumenie +PARTIALPASTE_COLORGROUP;Nastavenia súvisiace s farbou +PARTIALPASTE_COLORMIXER;Mixér farieb +PARTIALPASTE_COLORSHIFT;Farebný posun +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_HLRECOVERY;Obnova najvyšších svetiel +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_LUMADENOISE;Redukcia šumu v oblasti svietivosti +PARTIALPASTE_LUMINANCEGROUP;Nastavenia súvisiace so svietivosťou +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_CACHESTRAT1;Uprednostniť rýchlosť pred malou spotrebou pamäte +PREFERENCES_CACHESTRAT2;Uprednostniť malú spotrebu pamäte pred rýchlosťou +PREFERENCES_CACHESTRAT;Stratégia použitia 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_DEMOSAICINGALGO;Demozaikovací algoritmus +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_HINT;Tip +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_LIVETHUMBNAILS;Živé zmenšeniny (pomalšie) +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_OUTDIRHINT;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\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_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_SELECTICCDIRDLG;Vybrať adresár s ICC profilmi... +PREFERENCES_SELECTLANG;Vybrať si jazyk +PREFERENCES_SELECTMONITORPROFDLG;Vybrať ICC profil monitora... +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_SHOWONLYRAW;Ukazovať len RAW súbory +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_TAB_OUTPUT;Výstupné možnosti +PREFERENCES_THUMBSIZE;Veľkosť zmenšeniny +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_PLASTPHOTO;Posledná fotka +PROFILEPANEL_PLASTSAVED;Posledné uložené +PROFILEPANEL_PROFILE;Profil +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_DECODING;Dekódujem raw súbor... +PROGRESSBAR_DEMOSAICING;Demozaikujem... +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_FOCALLENGTH;Ohnisková vzdialenosť +QINFO_ISO;ISO +QINFO_LENS;Objektív +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_PNGFILTER;PNG súbory +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_OUTPUTDLGLABEL;Vybrať výstupný ICC profil... +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_LUMADENOISE_EDGETOLERANCE;Tolerancia okrajov +TP_LUMADENOISE_LABEL;Redukcia šumu v oblasti svietivosti +TP_LUMADENOISE_RADIUS;Polomer +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_FULLSIZE;Celá veľkosť obrázka: +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 +ZOOMBAR_DETAIL;Detail +ZOOMBAR_HUGE;Obrovský +ZOOMBAR_LARGE;Veľký +ZOOMBAR_NORMAL;Normálny +ZOOMBAR_PREVIEW;Náhľad +ZOOMBAR_SCALE;Rozmer +ZOOMBAR_SMALL;Malý +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;Otvoriť (nové) okno s detailom +ZOOMPANEL_ZOOM100;Priblíženie na 100% 1 +ZOOMPANEL_ZOOMFITSCREEN;Prispôsobiť obrazovke F +ZOOMPANEL_ZOOMIN;Priblížiť + +ZOOMPANEL_ZOOMOUT;Oddialiť - + +#00 Slovenčina +#01 08.05.2008 +#02 01.02.2009 +#03 23.10.2010 +#04 (Slapo) + +!!!!!!!!!!!!!!!!!!!!!!!!! +! 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 +!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_SHARPENEDGE;Bypass Edge Sharpening +!EXPORT_BYPASS_SHARPENING;Bypass Sharpening +!EXPORT_BYPASS_SHARPENMICRO;Bypass Microcontrast +!EXPORT_BYPASS_SH_HQ;Bypass Shadow/Highlights (High Quality) +!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 the path text box.\nEnter / Ctrl-Enter (in the File Browser) to browse there;\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_DARKFRAME;Dark frame +!FILEBROWSER_DELETEDLGMSGINCLPROC;Are you sure you want to delete the selected %1 files including a queue-processed version? +!FILEBROWSER_EXEC_CPB;Custom Profile Builder +!FILEBROWSER_EXTPROGMENU;Open with +!FILEBROWSER_FLATFIELD;Flat Field +!FILEBROWSER_MOVETODARKFDIR;Move to dark frames directory +!FILEBROWSER_MOVETOFLATFIELDDIR;Move to flat fields directory +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!FILEBROWSER_POPUPCOLORLABEL0;Label: None +!FILEBROWSER_POPUPCOLORLABEL1;Label: Red +!FILEBROWSER_POPUPCOLORLABEL2;Label: Yellow +!FILEBROWSER_POPUPCOLORLABEL3;Label: Green +!FILEBROWSER_POPUPCOLORLABEL4;Label: Blue +!FILEBROWSER_POPUPCOLORLABEL5;Label: Purple +!FILEBROWSER_POPUPCOLORLABEL;Color label +!FILEBROWSER_POPUPCOPYTO;Copy to... +!FILEBROWSER_POPUPFILEOPERATIONS;File Operations +!FILEBROWSER_POPUPMOVETO;Move to... +!FILEBROWSER_POPUPPROCESSFAST;Put to Queue (Fast export) +!FILEBROWSER_POPUPPROFILEOPERATIONS;Processing Profile Operations +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_POPUPREMOVESUBMENU;Remove +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!FILEBROWSER_QUERYHINT;Type a partial filename to search for.\nCtrl-F to focus the Find text box (in the File Browser).\nEnter to commence search. +!FILEBROWSER_QUERYLABEL; Find: +!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-` +!GENERAL_FILE;File +!GENERAL_NONE;None +!GENERAL_WARNING;Warning +!HISTOGRAM_BUTTON_BAR;RGB +!HISTOGRAM_BUTTON_RAW;Raw +!HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar\nClick right mouse button on image preview to freeze/unfreeze +!HISTOGRAM_TOOLTIP_FULL;Toggle full or scaled histogram +!HISTOGRAM_TOOLTIP_RAW;Show/Hide raw histogram +!HISTORY_MSG_88;Impulse NR Threshold +!HISTORY_MSG_93;Contrast by Detail Levels Value +!HISTORY_MSG_94;Contrast by Detail Levels +!HISTORY_MSG_95;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;RGB Saturation +!HISTORY_MSG_101;HSV EQ -- Hue +!HISTORY_MSG_102;HSV EQ -- Saturation +!HISTORY_MSG_103;HSV EQ -- Value +!HISTORY_MSG_104;HSV Equalizer +!HISTORY_MSG_105;Defringing +!HISTORY_MSG_106;Defringing Radius +!HISTORY_MSG_107;Defringing Threshold +!HISTORY_MSG_108;Highlight Compr. Threshold +!HISTORY_MSG_109;Resize Bounding Box +!HISTORY_MSG_110;Resizing applies o +!HISTORY_MSG_111;Avoid Color Shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;Red and Skin Tones Protection +!HISTORY_MSG_114;DCB Iterations +!HISTORY_MSG_115;False Color Iterations +!HISTORY_MSG_116;Enhanced DCB +!HISTORY_MSG_117;Red CA Correction +!HISTORY_MSG_118;Blue CA Correction +!HISTORY_MSG_119;Line Denoise +!HISTORY_MSG_120;Green Equil. Threshold +!HISTORY_MSG_121;Auto CA +!HISTORY_MSG_122;Auto Dark Frame +!HISTORY_MSG_123;Dark Frame File +!HISTORY_MSG_124;Linear Exp. Correction +!HISTORY_MSG_125;Exp. Correction Preserving HL +!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;Gamma +!HISTORY_MSG_134;Gamma Position +!HISTORY_MSG_135;Gamma Free +!HISTORY_MSG_136;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 Green Together +!HISTORY_MSG_142;Edges Sharpening - Iterations +!HISTORY_MSG_143;Edges Sharpening - Quantity +!HISTORY_MSG_144;Microcontrast - Quantity +!HISTORY_MSG_145;Microcontrast - Uniformity +!HISTORY_MSG_146;Edges Sharpening +!HISTORY_MSG_147;Edges Sharpening - 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;Vibrance - Pastel tones +!HISTORY_MSG_153;Vibrance - Saturated tones +!HISTORY_MSG_154;Vibrance - Protect skin tones +!HISTORY_MSG_155;Vibrance - Avoid color drift +!HISTORY_MSG_156;Vibrance - Link pastel and saturated tones +!HISTORY_MSG_157;Vibrance - Pastel/Saturated threshold +!HISTORY_MSG_158;Strength +!HISTORY_MSG_159;Edge Stopping +!HISTORY_MSG_160;Scale +!HISTORY_MSG_161;Reweighting Iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_163;RGB Curves - R +!HISTORY_MSG_164;RGB Curves - G +!HISTORY_MSG_165;RGB Curves - B +!HISTORY_MSG_166;Neutral Levels +!HISTORY_MSG_167;B&W Toning +!HISTORY_MSG_168;'Cc' curve +!HISTORY_MSG_169;'Ch' curve +!HISTORY_MSG_170;Vibrance - Curve +!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_TAB_COLOR_TOOLTIP;Shortcut: Alt-C +!MAIN_TAB_DETAIL_TOOLTIP;Shortcut: Alt-D +!MAIN_TAB_EXPORT; 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: 8 +!MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 0 +!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_CHANNELMIXER;Channel mixer +!PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto fill +!PARTIALPASTE_DARKFRAMEAUTOSELECT;Dark Frame Auto Select +!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;FF Auto Select +!PARTIALPASTE_FLATFIELDBLURRADIUS;FF Blur Radius +!PARTIALPASTE_FLATFIELDBLURTYPE;FF Blur Type +!PARTIALPASTE_FLATFIELDFILE;Flat field (FF) File +!PARTIALPASTE_HLRECONSTRUCTION;Highlight reconstruction +!PARTIALPASTE_HLRECOVERYAMOUNT;Highlight recovery amount +!PARTIALPASTE_HLRECOVERYTHRESHOLD;Highlight recovery threshold +!PARTIALPASTE_HSVEQUALIZER;HSV Equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!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 Level +!PARTIALPASTE_RAWEXPOS_LINEAR;Raw white point linear corr. factor +!PARTIALPASTE_RAWEXPOS_PRESER;Raw white point HL preserving corr. (EV) +!PARTIALPASTE_RAWGROUP;Raw settings +!PARTIALPASTE_RAW_ALLENHANCE;Apply post demosaic artifact/noise reduction +!PARTIALPASTE_RAW_DCBENHANCE;Apply DCB enhancement step +!PARTIALPASTE_RAW_DCBITERATIONS;Number of DCB iterations +!PARTIALPASTE_RAW_DMETHOD;Demosaic Method +!PARTIALPASTE_RAW_FALSECOLOR;Demosaic False color suppression steps +!PARTIALPASTE_RGBCURVES;RGB curves +!PARTIALPASTE_SHARPENEDGE;Edges +!PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_VIBRANCE;Vibrance +!PARTIALPASTE_WAVELETEQUALIZER;Wavelet equalizer +!PREFERENCES_AUTOMONPROFILE;Automatically use operating system's main monitor color profile +!PREFERENCES_CUSTPROFBUILDHINT;Executable (or script) file called when a new initial processing profile should be generated for an image.\nReceives command line parameters to allow a rules-based processing profile generation:\n[raw/JPG path] [default processing profile path] [f-number] [exposure in secs] [focal length in mm] [ISO] [lens] [camera] +!PREFERENCES_CUSTPROFBUILDPATH;Executable path +!PREFERENCES_CUSTPROFBUILD;Custom Processing Profile Builder +!PREFERENCES_CUTOVERLAYBRUSH;Crop mask color/transparency +!PREFERENCES_DARKFRAMEFOUND;Found +!PREFERENCES_DARKFRAMESHOTS;shots +!PREFERENCES_DARKFRAMETEMPLATES;templates +!PREFERENCES_DARKFRAME;Dark Frame +!PREFERENCES_DATEFORMATFRAME;Date Format +!PREFERENCES_DIRDARKFRAMES;Dark frames directory +!PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar (de-select for low res display) +!PREFERENCES_FLATFIELDFOUND;Found +!PREFERENCES_FLATFIELDSDIR;Flat Fields directory +!PREFERENCES_FLATFIELDSHOTS;shots +!PREFERENCES_FLATFIELDTEMPLATES;templates +!PREFERENCES_FLATFIELD;Flat Field +!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_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). On Windows use "SystemDefault", "SystemAsterisk" etc. for system sounds. +!PREFERENCES_SND_LNGEDITPROCDONE;Editor processing done +!PREFERENCES_SND_TRESHOLDSECS;after secs +!PREFERENCES_SQUAREDETAILWINDOW;Square detail window (faster) +!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) +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_SAVEPPASTE;Parameters to save +!PROGRESSBAR_BADPIXELS;Bad pixels... +!PROGRESSBAR_CACORRECTION;CA correction... +!PROGRESSBAR_DARKFRAME;Darkframe... +!PROGRESSBAR_GREENEQUIL;Green equilibrate... +!PROGRESSBAR_LINEDENOISE;Line Denoise... +!PROGRESSBAR_LOADINGTHUMBS;Loading thumbnails... +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing Profile Saved +!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\nthe 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_CHROMATABERR_LABEL;Chromatic Aberration +!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_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_EXPOSCORR_LABEL;Raw white & black points +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggle execution of Auto Levels to automatically set parameter values based on image analysis +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in auto levels operation +!TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Highlight recovery threshold +!TP_EXPOSURE_SATURATION;Saturation +!TP_EXPO_AFTER; After interpolation (before RGB conversion) +!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_HLREC_BLEND;Blend +!TP_HSVEQUALIZER_CHANNEL;HSV Channel +!TP_HSVEQUALIZER_HUE;H +!TP_HSVEQUALIZER_LABEL;HSV Equalizer +!TP_HSVEQUALIZER_NEUTRAL;Neutral +!TP_HSVEQUALIZER_SAT;S +!TP_HSVEQUALIZER_VAL;V +!TP_ICM_BLENDCMSMATRIX;Blend highlights with matrix +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover blown highlights when using LUT based ICC profiles +!TP_ICM_INPUTCAMERAICC;Auto-matched camera-specific color profile +!TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profile. These profiles are more precise than simpler matrix ones. Available for some 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_PREFERREDPROFILE;Preferred DCP profile +!TP_ICM_PREFERREDPROFILE_1;Daylight +!TP_ICM_PREFERREDPROFILE_2;Tungsten +!TP_ICM_PREFERREDPROFILE_3;Fluorescent +!TP_ICM_PREFERREDPROFILE_4;Flash +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid Color Shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space\nand apply Munsell correction +!TP_LABCURVE_BWTONING;B&W Toning +!TP_LABCURVE_BWTONING_TIP;With B&W Toning option enabled, the Lab Chromaticity, Cc and Ch curves are not in effect.\nToning can be achieved using the a and b curves +!TP_LABCURVE_CHROMATICITY;Chromaticity +!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 the Chromaticity +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to the Hue +!TP_LABCURVE_RSTPROTECTION;Red and Skin Tones Protection +!TP_LENSPROFILE_FILEDLGFILTERLCP;Lens correction files +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;Use CA correction +!TP_LENSPROFILE_USEDIST;Use distortion correction +!TP_LENSPROFILE_USEVIGN;Use vignette correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset exposure controls to neutral values +!TP_PREPROCESS_HOTDEADPIXTHRESH;Hot/dead pixel detection threshold +!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 (leader) +!TP_RAWEXPOS_LINEAR;White Point: Linear corr. factor +!TP_RAWEXPOS_PRESER;White Point: HL preserving corr.(EV) +!TP_RAWEXPOS_TWOGREEN;Two greens together +!TP_RAW_ALLENHANCE;Apply post demosaic artifact/noise reduction +!TP_RAW_LABEL;Demosaicing +!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_RED;R +!TP_SHARPENEDGE_AMOUNT;Quantity +!TP_SHARPENEDGE_LABEL;Edges +!TP_SHARPENEDGE_PASSES;Iterations +!TP_SHARPENEDGE_THREE;Luminance only +!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 the Hue +!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_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 diff --git a/rtdata/languages/Suomi b/rtdata/languages/Suomi new file mode 100644 index 000000000..110b27cee --- /dev/null +++ b/rtdata/languages/Suomi @@ -0,0 +1,1208 @@ +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_DIALOGLABEL;EXIF suodatus +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_ARRANGEMENTHINT;Vaihda esikatselukuvien ryhmittely vaaka/pysty suunnassa +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_EXIFFILTERAPPLYHINT;EXIF suodatus päälle/pois +FILEBROWSER_EXIFFILTERAPPLY;Päällä +FILEBROWSER_EXIFFILTERLABEL;EXIF suodatus +FILEBROWSER_EXIFFILTERSETTINGSHINT;Määritä exit suodatuksen asetukset +FILEBROWSER_EXIFFILTERSETTINGS;Asetukset +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_POPUPRANK1;1 tähti +FILEBROWSER_POPUPRANK2;2 tähteä +FILEBROWSER_POPUPRANK3;3 tähteä +FILEBROWSER_POPUPRANK4;4 tähteä +FILEBROWSER_POPUPRANK5;5 tähteä +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_PROCESSINGSETTINGSHINT;Tallennusasetukset +FILEBROWSER_PROCESSINGSETTINGS;Asetukset +FILEBROWSER_RENAMEDLGLABEL;Nimeä uudelleen +FILEBROWSER_RENAMEDLGMSG;Tiedoston "%1" uusi nimi: +FILEBROWSER_SHOWDIRHINT;Näytä hakemiston kaikki kuvat +FILEBROWSER_SHOWQUEUEHINT;Näytä käsittelyjono +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_LOAD;Lataa +GENERAL_NA;- +GENERAL_NO;Ei +GENERAL_OK;OK +GENERAL_PORTRAIT;Pysty +GENERAL_SAVE;Tallenna +GENERAL_YES;Kyllä +HISTOGRAM_LABEL;Histogrammi +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_NEWSNAPSHOTAS;... +HISTORY_NEWSNAPSHOT;Uusi pikakuva +HISTORY_NEWSSDIALOGLABEL;Pikakuvan nimi: +HISTORY_NEWSSDIALOGTITLE;Lisää uusi pikakuva +HISTORY_SETTO;Aseta +HISTORY_SNAPSHOTS;Pikakuvat +HISTORY_SNAPSHOT;Pikakuva +ICMPANEL_FILEDLGFILTERANY;kaikki tiedostot +ICMPANEL_FILEDLGFILTERICM;ICC-profiilitiedostot +ICMPANEL_GAMMABEFOREINPUT;Käytä profiilin gammaa +ICMPANEL_INPUTCAMERA;Kameran oletus +ICMPANEL_INPUTCUSTOM;Oma +ICMPANEL_INPUTDLGLABEL;Valitse lähteen ICC-profiili... +ICMPANEL_INPUTEMBEDDED;Käytä kuvan omaa, jos mahdollista +ICMPANEL_INPUTPROFILE;Lähdeväriprofiili +ICMPANEL_NOICM;Ei ICM-profiilia: sRGB +ICMPANEL_OUTPUTDLGLABEL;Valitse tuloksen ICC-profiili... +ICMPANEL_OUTPUTPROFILE;Tulosväriprofiili +ICMPANEL_SAVEREFERENCE;Tallenna mallikuva\nprofilointia varten +ICMPANEL_WORKINGPROFILE;Työväriprofiili +IMAGEAREA_DETAILVIEW; +IPTCPANEL_AUTHORHINT;(Author) Kuvaajan nimi. +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_EXIT;Exit +MAIN_BUTTON_PREFERENCES;Asetukset +MAIN_BUTTON_QUEUE;Put to queue +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_EXITJOBSINQUEUEINFO;Käsittelemättömät kuvat jonossa menetetään poistuttaessa. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Haluatko varmasti lopettaa? Jonossa on käsittelemättömiä kuvia. +MAIN_MSG_JOBSINQUEUE;työtä jonossa +MAIN_MSG_QOVERWRITE;Haluatko tallentaa päälle? +MAIN_TAB_BASIC;Säädöt +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_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metatiedot +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;Muunnokset +MAIN_TOOLTIP_HIDEFP;Näytä/piilota alaikkuna (pikanäppäin: F) +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_PREFERENCES;Muuta asetuksia +MAIN_TOOLTIP_QINFO;Kuvan tiedot +MAIN_TOOLTIP_SAVEAS;Tallenna kuva\nvalittuun hakemistoon +MAIN_TOOLTIP_SAVE;Tallenna kuva\noletushakemistoon +PARTIALPASTE_BASICGROUP;Perusasetukset +PARTIALPASTE_CACORRECTION;Väripoikkeaman korjaus +PARTIALPASTE_COARSETRANS;Vasen/oikea kääntö ja peilaus +PARTIALPASTE_COLORBOOST;Värikylläisyys +PARTIALPASTE_COLORDENOISE;Värin kohinanvaimennus +PARTIALPASTE_COLORGROUP;Väriasetukset +PARTIALPASTE_COLORMIXER;Kanavat +PARTIALPASTE_COLORSHIFT;Värisävy +PARTIALPASTE_COMPOSITIONGROUP;Muunnokset +PARTIALPASTE_CROP;Rajaus +PARTIALPASTE_DIALOGLABEL;Liitä valiten.. +PARTIALPASTE_DISTORTION;Linssivääristymän korjaus +PARTIALPASTE_EXIFCHANGES;EXIF-tiedot +PARTIALPASTE_EXPOSURE;Valotus +PARTIALPASTE_HLRECOVERY;Huippuvaloalueiden palautus +PARTIALPASTE_ICMSETTINGS;ICM-profiili +PARTIALPASTE_IPTCINFO;IPTC-tiedot +PARTIALPASTE_LENSGROUP;Objektiiviin liittyvät asetukset +PARTIALPASTE_LUMACURVE;Luminanssikäyrä +PARTIALPASTE_LUMADENOISE;Luminanssin kohinanpoisto +PARTIALPASTE_LUMINANCEGROUP;Lisäasetukset +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_CACHESTRAT1;Suosi nopeutta muistin kustannuksella +PREFERENCES_CACHESTRAT2;Suosi muistia nopeuden kustannuksella +PREFERENCES_CACHESTRAT;Välimuistin optimointitapa +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_DEMOSAICINGALGO;Väri-interpolointi +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_HINT;Neuvo +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_LIVETHUMBNAILS;Jatkuvasti päivittyvä esikatselu (hidas) +PREFERENCES_MONITORICC;Näytön profiili +PREFERENCES_OUTDIRFOLDERHINT;Tallenna kuvat valittuun kansioon +PREFERENCES_OUTDIRFOLDER;Valitse hakemisto +PREFERENCES_OUTDIRHINT;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_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_SELECTICCDIRDLG;Valitse ICC-profiilin hakemisto... +PREFERENCES_SELECTLANG;Valitse kieli +PREFERENCES_SELECTMONITORPROFDLG;Valitse näytön ICC-profiili... +PREFERENCES_SELECTTHEME;Valitse teema +PREFERENCES_SHOWBASICEXIF;Perus EXIF-tiedot +PREFERENCES_SHOWDATETIME;Päivämäärä ja aika +PREFERENCES_SHOWONLYRAW;Näytä vain RAW-tiedostot +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 +PREFERENCES_TAB_OUTPUT;Tallennus +PREFERENCES_THUMBSIZE;Esikatselukuvien koko +PROFILEPANEL_FILEDLGFILTERANY;Kaikki tiedostot +PROFILEPANEL_FILEDLGFILTERPP;Profiilitiedostot +PROFILEPANEL_LABEL;Käsittelyprofiili +PROFILEPANEL_LOADDLGLABEL;Lataa käsittelyprofiili... +PROFILEPANEL_PCUSTOM;Oma +PROFILEPANEL_PFILE;Tiedostosta +PROFILEPANEL_PLASTPHOTO;Viimeisimmästä kuvasta +PROFILEPANEL_PLASTSAVED;Viimeisin tallennettu +PROFILEPANEL_PROFILE;Profiili +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_DECODING;RAW-tiedostoa puretaan... +PROGRESSBAR_DEMOSAICING;Kuvaa koostetaan... +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_FOCALLENGTH;Polttoväli +QINFO_ISO;ISO +QINFO_LENS;Objektiivi +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_PNGFILTER;PNG tiedostot +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_OUTPUTDLGLABEL;Valitse tuloksen ICC-profiili... +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_LUMADENOISE_EDGETOLERANCE;Reunan tunnistusherkkyys +TP_LUMADENOISE_LABEL;Luminanssin kohinanvaimennus +TP_LUMADENOISE_RADIUS;Säde +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_FULLSIZE;Kuvan koko: +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] +ZOOMBAR_DETAIL; +ZOOMBAR_HUGE;Suurin +ZOOMBAR_LARGE;Suuri +ZOOMBAR_NORMAL;Normaali +ZOOMBAR_PREVIEW; +ZOOMBAR_SCALE; +ZOOMBAR_SMALL;Pieni + +#00 Finnish +#01 Compiled by T.Kauppinen 3.5.2009 +# + +!!!!!!!!!!!!!!!!!!!!!!!!! +! 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 +!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_SHARPENEDGE;Bypass Edge Sharpening +!EXPORT_BYPASS_SHARPENING;Bypass Sharpening +!EXPORT_BYPASS_SHARPENMICRO;Bypass Microcontrast +!EXPORT_BYPASS_SH_HQ;Bypass Shadow/Highlights (High Quality) +!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 the path text box.\nEnter / Ctrl-Enter (in the File Browser) to browse there;\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_CURRENT_NAME;Current name: +!FILEBROWSER_DARKFRAME;Dark frame +!FILEBROWSER_DELETEDLGMSGINCLPROC;Are you sure you want to delete the selected %1 files including a queue-processed version? +!FILEBROWSER_EXEC_CPB;Custom Profile Builder +!FILEBROWSER_EXTPROGMENU;Open with +!FILEBROWSER_FLATFIELD;Flat Field +!FILEBROWSER_MOVETODARKFDIR;Move to dark frames directory +!FILEBROWSER_MOVETOFLATFIELDDIR;Move to flat fields directory +!FILEBROWSER_NEW_NAME;New name: +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!FILEBROWSER_POPUPCOLORLABEL0;Label: None +!FILEBROWSER_POPUPCOLORLABEL1;Label: Red +!FILEBROWSER_POPUPCOLORLABEL2;Label: Yellow +!FILEBROWSER_POPUPCOLORLABEL3;Label: Green +!FILEBROWSER_POPUPCOLORLABEL4;Label: Blue +!FILEBROWSER_POPUPCOLORLABEL5;Label: Purple +!FILEBROWSER_POPUPCOLORLABEL;Color label +!FILEBROWSER_POPUPCOPYTO;Copy to... +!FILEBROWSER_POPUPFILEOPERATIONS;File Operations +!FILEBROWSER_POPUPMOVETO;Move to... +!FILEBROWSER_POPUPPROCESSFAST;Put to Queue (Fast export) +!FILEBROWSER_POPUPPROFILEOPERATIONS;Processing Profile Operations +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_POPUPREMOVESUBMENU;Remove +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!FILEBROWSER_QUERYHINT;Type a partial filename to search for.\nCtrl-F to focus the Find text box (in the File Browser).\nEnter to commence search. +!FILEBROWSER_QUERYLABEL; Find: +!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 +!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-` +!FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +!FILEBROWSER_USETEMPLATE;Use template: +!GENERAL_AFTER;After +!GENERAL_BEFORE;Before +!GENERAL_FILE;File +!GENERAL_HIGH_QUALITY;High Quality +!GENERAL_NONE;None +!GENERAL_UNCHANGED;(Unchanged) +!GENERAL_WARNING;Warning +!HISTOGRAM_BUTTON_BAR;RGB +!HISTOGRAM_BUTTON_B;B +!HISTOGRAM_BUTTON_G;G +!HISTOGRAM_BUTTON_L;L +!HISTOGRAM_BUTTON_RAW;Raw +!HISTOGRAM_BUTTON_R;R +!HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar\nClick right mouse button on image preview to freeze/unfreeze +!HISTOGRAM_TOOLTIP_FULL;Toggle full or scaled histogram +!HISTOGRAM_TOOLTIP_RAW;Show/Hide raw histogram +!HISTORY_MSG_82;Profile Changed +!HISTORY_MSG_83;High Quality Shadows/Highlights +!HISTORY_MSG_84;Perspective Correction +!HISTORY_MSG_85;Lens Correction Profile +!HISTORY_MSG_86;Wavelet Equalizer +!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 +!HISTORY_MSG_92;NR - Gamma +!HISTORY_MSG_93;Contrast by Detail Levels Value +!HISTORY_MSG_94;Contrast by Detail Levels +!HISTORY_MSG_95;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;RGB Saturation +!HISTORY_MSG_101;HSV EQ -- Hue +!HISTORY_MSG_102;HSV EQ -- Saturation +!HISTORY_MSG_103;HSV EQ -- Value +!HISTORY_MSG_104;HSV Equalizer +!HISTORY_MSG_105;Defringing +!HISTORY_MSG_106;Defringing Radius +!HISTORY_MSG_107;Defringing Threshold +!HISTORY_MSG_108;Highlight Compr. Threshold +!HISTORY_MSG_109;Resize Bounding Box +!HISTORY_MSG_110;Resizing applies o +!HISTORY_MSG_111;Avoid Color Shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;Red and Skin Tones Protection +!HISTORY_MSG_114;DCB Iterations +!HISTORY_MSG_115;False Color Iterations +!HISTORY_MSG_116;Enhanced DCB +!HISTORY_MSG_117;Red CA Correction +!HISTORY_MSG_118;Blue CA Correction +!HISTORY_MSG_119;Line Denoise +!HISTORY_MSG_120;Green Equil. Threshold +!HISTORY_MSG_121;Auto CA +!HISTORY_MSG_122;Auto Dark Frame +!HISTORY_MSG_123;Dark Frame File +!HISTORY_MSG_124;Linear Exp. Correction +!HISTORY_MSG_125;Exp. Correction Preserving HL +!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;Gamma +!HISTORY_MSG_134;Gamma Position +!HISTORY_MSG_135;Gamma Free +!HISTORY_MSG_136;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 Green Together +!HISTORY_MSG_142;Edges Sharpening - Iterations +!HISTORY_MSG_143;Edges Sharpening - Quantity +!HISTORY_MSG_144;Microcontrast - Quantity +!HISTORY_MSG_145;Microcontrast - Uniformity +!HISTORY_MSG_146;Edges Sharpening +!HISTORY_MSG_147;Edges Sharpening - 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;Vibrance - Pastel tones +!HISTORY_MSG_153;Vibrance - Saturated tones +!HISTORY_MSG_154;Vibrance - Protect skin tones +!HISTORY_MSG_155;Vibrance - Avoid color drift +!HISTORY_MSG_156;Vibrance - Link pastel and saturated tones +!HISTORY_MSG_157;Vibrance - Pastel/Saturated threshold +!HISTORY_MSG_158;Strength +!HISTORY_MSG_159;Edge Stopping +!HISTORY_MSG_160;Scale +!HISTORY_MSG_161;Reweighting Iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_163;RGB Curves - R +!HISTORY_MSG_164;RGB Curves - G +!HISTORY_MSG_165;RGB Curves - B +!HISTORY_MSG_166;Neutral Levels +!HISTORY_MSG_167;B&W Toning +!HISTORY_MSG_168;'Cc' curve +!HISTORY_MSG_169;'Ch' curve +!HISTORY_MSG_170;Vibrance - Curve +!MAIN_BUTTON_FULLSCREEN;Fullscreen +!MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Put current image to processing queue.\nShortcut: Ctrl+Q +!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_ERRORDURINGIMAGESAVING;Error during image saving +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue processed first. +!MAIN_MSG_NAVIGATOR;Navigator +!MAIN_MSG_PLACES;Places +!MAIN_TAB_COLOR_TOOLTIP;Shortcut: Alt-C +!MAIN_TAB_DETAIL_TOOLTIP;Shortcut: Alt-D +!MAIN_TAB_EXPORT; 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_TOGGLE_BEFORE_AFTER;B|A +!MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 8 +!MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 0 +!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_CHANNELMIXER;Channel mixer +!PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto fill +!PARTIALPASTE_DARKFRAMEAUTOSELECT;Dark Frame Auto Select +!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;FF Auto Select +!PARTIALPASTE_FLATFIELDBLURRADIUS;FF Blur Radius +!PARTIALPASTE_FLATFIELDBLURTYPE;FF Blur Type +!PARTIALPASTE_FLATFIELDFILE;Flat field (FF) File +!PARTIALPASTE_HLRECONSTRUCTION;Highlight reconstruction +!PARTIALPASTE_HLRECOVERYAMOUNT;Highlight recovery amount +!PARTIALPASTE_HLRECOVERYTHRESHOLD;Highlight recovery threshold +!PARTIALPASTE_HSVEQUALIZER;HSV Equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!PARTIALPASTE_LABCURVE;Lab adjustments +!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 Level +!PARTIALPASTE_RAWEXPOS_LINEAR;Raw white point linear corr. factor +!PARTIALPASTE_RAWEXPOS_PRESER;Raw white point HL preserving corr. (EV) +!PARTIALPASTE_RAWGROUP;Raw settings +!PARTIALPASTE_RAW_ALLENHANCE;Apply post demosaic artifact/noise reduction +!PARTIALPASTE_RAW_DCBENHANCE;Apply DCB enhancement step +!PARTIALPASTE_RAW_DCBITERATIONS;Number of DCB iterations +!PARTIALPASTE_RAW_DMETHOD;Demosaic Method +!PARTIALPASTE_RAW_FALSECOLOR;Demosaic False color suppression steps +!PARTIALPASTE_RGBCURVES;RGB curves +!PARTIALPASTE_SHARPENEDGE;Edges +!PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_VIBRANCE;Vibrance +!PARTIALPASTE_WAVELETEQUALIZER;Wavelet equalizer +!PREFERENCES_ADD;ADD +!PREFERENCES_AUTOMONPROFILE;Automatically use operating system's main monitor color profile +!PREFERENCES_BATCH_PROCESSING;Batch Processing +!PREFERENCES_BEHAVIOR;Behavior +!PREFERENCES_CUSTPROFBUILDHINT;Executable (or script) file called when a new initial processing profile should be generated for an image.\nReceives command line parameters to allow a rules-based processing profile generation:\n[raw/JPG path] [default processing profile path] [f-number] [exposure in secs] [focal length in mm] [ISO] [lens] [camera] +!PREFERENCES_CUSTPROFBUILDPATH;Executable path +!PREFERENCES_CUSTPROFBUILD;Custom Processing Profile Builder +!PREFERENCES_CUTOVERLAYBRUSH;Crop mask color/transparency +!PREFERENCES_DARKFRAMEFOUND;Found +!PREFERENCES_DARKFRAMESHOTS;shots +!PREFERENCES_DARKFRAMETEMPLATES;templates +!PREFERENCES_DARKFRAME;Dark Frame +!PREFERENCES_DATEFORMATFRAME;Date Format +!PREFERENCES_DIRDARKFRAMES;Dark frames directory +!PREFERENCES_EDITORLAYOUT;Editor Layout +!PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar (de-select for low res display) +!PREFERENCES_FLATFIELDFOUND;Found +!PREFERENCES_FLATFIELDSDIR;Flat Fields directory +!PREFERENCES_FLATFIELDSHOTS;shots +!PREFERENCES_FLATFIELDTEMPLATES;templates +!PREFERENCES_FLATFIELD;Flat Field +!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_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). On Windows use "SystemDefault", "SystemAsterisk" etc. for system sounds. +!PREFERENCES_SND_LNGEDITPROCDONE;Editor processing done +!PREFERENCES_SND_TRESHOLDSECS;after secs +!PREFERENCES_SQUAREDETAILWINDOW;Square detail window (faster) +!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_USESYSTEMTHEME; Use system theme +!PREFERENCES_WORKFLOW;Layout +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_SAVEPPASTE;Parameters to save +!PROGRESSBAR_BADPIXELS;Bad pixels... +!PROGRESSBAR_CACORRECTION;CA correction... +!PROGRESSBAR_DARKFRAME;Darkframe... +!PROGRESSBAR_GREENEQUIL;Green equilibrate... +!PROGRESSBAR_LINEDENOISE;Line Denoise... +!PROGRESSBAR_LOADINGTHUMBS;Loading thumbnails... +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing Profile Saved +!PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists +!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\nthe 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_CHROMATABERR_LABEL;Chromatic Aberration +!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_DETAIL_AMOUNT;Amount +!TP_DIRPYRDENOISE_CHROMA;Chrominance +!TP_DIRPYRDENOISE_GAMMA;Gamma +!TP_DIRPYRDENOISE_LABEL;Noise reduction +!TP_DIRPYRDENOISE_LUMA;Luminance +!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_EQUALIZER_CONTRAST_MINUS;Contrast- +!TP_EQUALIZER_CONTRAST_PLUS;Contrast+ +!TP_EQUALIZER_FINEST;finest +!TP_EQUALIZER_LABEL;Wavelet equalizer +!TP_EQUALIZER_LARGEST;coarsest +!TP_EQUALIZER_NEUTRAL;Neutral +!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 +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in auto levels operation +!TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Highlight recovery threshold +!TP_EXPOSURE_SATURATION;Saturation +!TP_EXPO_AFTER; After interpolation (before RGB conversion) +!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_HLREC_BLEND;Blend +!TP_HSVEQUALIZER_CHANNEL;HSV Channel +!TP_HSVEQUALIZER_HUE;H +!TP_HSVEQUALIZER_LABEL;HSV Equalizer +!TP_HSVEQUALIZER_NEUTRAL;Neutral +!TP_HSVEQUALIZER_SAT;S +!TP_HSVEQUALIZER_VAL;V +!TP_ICM_BLENDCMSMATRIX;Blend highlights with matrix +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover blown highlights when using LUT based ICC profiles +!TP_ICM_INPUTCAMERAICC;Auto-matched camera-specific color profile +!TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profile. These profiles are more precise than simpler matrix ones. Available for some 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_PREFERREDPROFILE;Preferred DCP profile +!TP_ICM_PREFERREDPROFILE_1;Daylight +!TP_ICM_PREFERREDPROFILE_2;Tungsten +!TP_ICM_PREFERREDPROFILE_3;Fluorescent +!TP_ICM_PREFERREDPROFILE_4;Flash +!TP_IMPULSEDENOISE_LABEL;Impulse Noise Reduction +!TP_IMPULSEDENOISE_THRESH;Impulse NR Threshold +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid Color Shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space\nand apply Munsell correction +!TP_LABCURVE_BRIGHTNESS;Brightness +!TP_LABCURVE_BWTONING;B&W Toning +!TP_LABCURVE_BWTONING_TIP;With B&W Toning option enabled, the Lab Chromaticity, Cc and Ch curves are not in effect.\nToning can be achieved using the a and b curves +!TP_LABCURVE_CHROMATICITY;Chromaticity +!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 the Chromaticity +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to the Hue +!TP_LABCURVE_LABEL;Lab Adjustments +!TP_LABCURVE_RSTPROTECTION;Red and Skin Tones Protection +!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;Use CA correction +!TP_LENSPROFILE_USEDIST;Use distortion correction +!TP_LENSPROFILE_USEVIGN;Use vignette correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset exposure controls to neutral values +!TP_PERSPECTIVE_HORIZONTAL;Horizontal +!TP_PERSPECTIVE_LABEL;Perspective +!TP_PERSPECTIVE_VERTICAL;Vertical +!TP_PREPROCESS_GREENEQUIL;Green equilibration +!TP_PREPROCESS_HOTDEADPIXFILT;Apply hot/dead pixel filter +!TP_PREPROCESS_HOTDEADPIXTHRESH;Hot/dead pixel detection threshold +!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 (leader) +!TP_RAWEXPOS_LINEAR;White Point: Linear corr. factor +!TP_RAWEXPOS_PRESER;White Point: HL preserving corr.(EV) +!TP_RAWEXPOS_TWOGREEN;Two greens together +!TP_RAW_ALLENHANCE;Apply post demosaic artifact/noise reduction +!TP_RAW_DCBENHANCE;Apply DCB enhancement step +!TP_RAW_DCBITERATIONS;Number of DCB iterations +!TP_RAW_LABEL;Demosaicing +!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_RED;R +!TP_SHARPENEDGE_AMOUNT;Quantity +!TP_SHARPENEDGE_LABEL;Edges +!TP_SHARPENEDGE_PASSES;Iterations +!TP_SHARPENEDGE_THREE;Luminance only +!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 the Hue +!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_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 +!ZOOMPANEL_100;(100%) +!ZOOMPANEL_NEWCROPWINDOW;Open (new) detail window +!ZOOMPANEL_ZOOM100;Zoom to 100% 1 +!ZOOMPANEL_ZOOMFITSCREEN;Fit to screen F +!ZOOMPANEL_ZOOMIN;Zoom In + +!ZOOMPANEL_ZOOMOUT;Zoom Out - diff --git a/rtdata/languages/Swedish b/rtdata/languages/Swedish new file mode 100644 index 000000000..926245733 --- /dev/null +++ b/rtdata/languages/Swedish @@ -0,0 +1,1242 @@ +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 +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_DIALOGLABEL;EXIF-filter +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å (rå) reducering av kromatiska abberationer +EXPORT_BYPASS_RAW_DCB_ITERATIONS;Förbigå (rå) DCB-iterationer +EXPORT_BYPASS_RAW_DF;Förbigå (rå) svartbild +EXPORT_BYPASS_RAW_FF;Förbigå (rå) plattfält +EXPORT_BYPASS_RAW_GREENTHRESH;Förbigå (rå) grönbalansering +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_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_ARRANGEMENTHINT;Växla mellan vertikal och horistonell visning av miniatyrbilder +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) +FILEBROWSER_CACHECLEARFROMFULL;Rensa från cachen - fullständigt +FILEBROWSER_CACHECLEARFROMPARTIAL;Rensa från cachen - delvis +FILEBROWSER_CACHE;Cache +FILEBROWSER_CLEARPROFILE;Återställ profilen +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_EXIFFILTERAPPLYHINT;Visa/dölj EXIF-filtret i filhanteraren +FILEBROWSER_EXIFFILTERAPPLY;Använd +FILEBROWSER_EXIFFILTERLABEL;EXIF-filter +FILEBROWSER_EXIFFILTERSETTINGSHINT;Ändra inställningar för EXIF-filtret +FILEBROWSER_EXIFFILTERSETTINGS;Inställningar +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_POPUPCOLORLABEL0;Etikett: Ingen +FILEBROWSER_POPUPCOLORLABEL1;Etikett: Röd +FILEBROWSER_POPUPCOLORLABEL2;Etikett: Gul +FILEBROWSER_POPUPCOLORLABEL3;Etikett: Grön +FILEBROWSER_POPUPCOLORLABEL4;Etikett: Blå +FILEBROWSER_POPUPCOLORLABEL5;Etikett: Lila +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_POPUPRANK1;Betyg 1 +FILEBROWSER_POPUPRANK2;Betyg 2 +FILEBROWSER_POPUPRANK3;Betyg 3 +FILEBROWSER_POPUPRANK4;Betyg 4 +FILEBROWSER_POPUPRANK5;Betyg 5 +FILEBROWSER_POPUPREMOVEINCLPROC;Ta bort från filsystemet inkl. den behandlade +FILEBROWSER_POPUPREMOVESUBMENU;Ta bort +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_PROCESSINGSETTINGSHINT;Ange filformat och målkatalog +FILEBROWSER_PROCESSINGSETTINGS;Inställningar +FILEBROWSER_QUERYBUTTONHINT;Rensa hittafältet +FILEBROWSER_QUERYHINT;Skriv in en del av filnamnet att söka efter. \nTryck Ctrl-f (i filhanteraren) för att sätta fokus i sökfältet och tryck Enter för att söka +FILEBROWSER_QUERYLABEL; Hitta: +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 Alt-1 +FILEBROWSER_SHOWCOLORLABEL2HINT;Visa bilder märkta som gulaAlt-2 +FILEBROWSER_SHOWCOLORLABEL3HINT;Visa bilder märkta som grönaAlt-3 +FILEBROWSER_SHOWCOLORLABEL4HINT;Visa bilder märkta som blåAlt-4 +FILEBROWSER_SHOWCOLORLABEL5HINT;Visa bilder märkta som lila Alt-5 +FILEBROWSER_SHOWDIRHINT;Visa alla bilder i biblioteket +FILEBROWSER_SHOWEDITEDHINT;Visa redigerade bilder 7 +FILEBROWSER_SHOWEDITEDNOTHINT;Visa ickeredigerade bilder 6 +FILEBROWSER_SHOWEXIFINFO;Visa EXIF-information +FILEBROWSER_SHOWQUEUEHINT;Visa innehållet i behandlingskön +FILEBROWSER_SHOWRANK1HINT;Visa bilder med betyg 1 +FILEBROWSER_SHOWRANK2HINT;Visa bilder med betyg 2 +FILEBROWSER_SHOWRANK3HINT;Visa bilder med betyg 3 +FILEBROWSER_SHOWRANK4HINT;Visa bilder med betyg 4 +FILEBROWSER_SHOWRANK5HINT;Visa bilder med betyg 5 +FILEBROWSER_SHOWRECENTLYSAVEDHINT;Visa bilder som nyligen sparats Alt-7 +FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Visa bilder som inte nyligen sparats Alt-6 +FILEBROWSER_SHOWTRASHHINT;Visa innehållet i papperskorgen +FILEBROWSER_SHOWUNCOLORHINT;Visa bilder utan färgetikett Alt-` +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_USETEMPLATE;Använd förinställning: +FILEBROWSER_ZOOMINHINT;Förstora miniatyrbilderna +FILEBROWSER_ZOOMOUTHINT;Förminska miniatyrbilderna +GENERAL_ABOUT;Om +GENERAL_AFTER;Efter +GENERAL_BEFORE;Före +GENERAL_CANCEL;Avbryt +GENERAL_DISABLED;Avaktivera +GENERAL_DISABLE;Avaktivera +GENERAL_ENABLED;Verkställ +GENERAL_ENABLE;Verkställ +GENERAL_FILE;Fil +GENERAL_HIGH_QUALITY;Hög kvalitet +GENERAL_LANDSCAPE;Landskap +GENERAL_LOAD;Ladda +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_YES;Ja +HISTOGRAM_BUTTON_BAR;RGB +HISTOGRAM_BUTTON_B;B +HISTOGRAM_BUTTON_G;G +HISTOGRAM_BUTTON_L;L +HISTOGRAM_BUTTON_RAW;Råbild +HISTOGRAM_BUTTON_R;R +HISTOGRAM_LABEL;Histogram +HISTOGRAM_TOOLTIP_BAR;Visa/dölj RBG-indikatorer Klicka på höger musknapp på förhandsvisningen för att frysa +HISTOGRAM_TOOLTIP_B;Visa/dölj blått 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;Exponeringskomprimering +HISTORY_MSG_9;Högdageråterställning +HISTORY_MSG_10;Skuggkomprimering +HISTORY_MSG_11;Tonkurva +HISTORY_MSG_12;Autoexponering +HISTORY_MSG_13;Exponeringsmarkering +HISTORY_MSG_14;Luminansljusstyrka +HISTORY_MSG_15;Luminanskontrast +HISTORY_MSG_16;Svart luminans +HISTORY_MSG_17;Luminans högdagerkompr. +HISTORY_MSG_18;Luminans skuggkompr. +HISTORY_MSG_19;Luminanskurva +HISTORY_MSG_20;Skärpning +HISTORY_MSG_21;Skärpningsradie +HISTORY_MSG_22;Skärpningsmängd +HISTORY_MSG_23;Skärpningströskelvärde +HISTORY_MSG_24;Skärp bara kanter +HISTORY_MSG_25;Kantupptäckningsradie-skärpning +HISTORY_MSG_26;Kantskärpningstolerans +HISTORY_MSG_27;Halo-skärpningskontroll +HISTORY_MSG_28;Halo-kontrollstorlek +HISTORY_MSG_29;Skärpningsmetod +HISTORY_MSG_30;Deconvolution-radie +HISTORY_MSG_31;Deconvolution-storlek +HISTORY_MSG_32;Deconvolution-dämpning +HISTORY_MSG_33;Deconvolution-upprepning +HISTORY_MSG_34;Undvik att färgen klipper +HISTORY_MSG_35;Mättnadsbegränsning +HISTORY_MSG_36;Mättnadsgräns +HISTORY_MSG_37;Färgförstärkning +HISTORY_MSG_38;Vitbalansmetod +HISTORY_MSG_39;Färgtemperatur +HISTORY_MSG_40;Färgton +HISTORY_MSG_41;Färgskiftning "A" +HISTORY_MSG_42;Färgskiftning "B" +HISTORY_MSG_43;Reducering av luminansbrus +HISTORY_MSG_44;Borttagningsradie för luminansbrusreducering +HISTORY_MSG_45;Kanttolerans för luminansbrusreducering +HISTORY_MSG_46;Färgbrusreducering +HISTORY_MSG_47;Radie för färgbrusreducering +HISTORY_MSG_48;Kanttolerans för färgbrusreducering +HISTORY_MSG_49;Kantkänslighet för färgbrusreducering +HISTORY_MSG_50;Skugg/högdagerverktyg +HISTORY_MSG_51;Högdagerförstärkning +HISTORY_MSG_52;Skuggförstärkning +HISTORY_MSG_53;Högdagertonvidd +HISTORY_MSG_54;Skuggtonvidd +HISTORY_MSG_55;Lokal kontrast +HISTORY_MSG_56;Skugg/högdagerradie +HISTORY_MSG_57;Enkel rotation +HISTORY_MSG_58;Vänd horisontellt +HISTORY_MSG_59;Vänd vertikalt +HISTORY_MSG_60;Rotation +HISTORY_MSG_61;Fyll automatiskt +HISTORY_MSG_62;Korrigering av objektivdistorsion +HISTORY_MSG_63;Valt bokmärke +HISTORY_MSG_64;Beskär foto +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;Korrigering av vinjettering +HISTORY_MSG_73;Kanalmixer +HISTORY_MSG_74;Ändra storleksskala +HISTORY_MSG_75;Ändra storleksmetod +HISTORY_MSG_76;EXIF Metadata +HISTORY_MSG_77;IPTC Metadata +HISTORY_MSG_78;Data som ska ändra storlek +HISTORY_MSG_79;Storleksförändring, bredd +HISTORY_MSG_80;Storleksförändring, höjd +HISTORY_MSG_81;Storleksförändring aktiverad +HISTORY_MSG_82;Profilen har ändrats +HISTORY_MSG_83;Högkvalitet Skuggor/högdagrar +HISTORY_MSG_84;Korrigering av perspektiv +HISTORY_MSG_85;Waveletkoefficienter +HISTORY_MSG_86;Waveletequalizer +HISTORY_MSG_87;Brusreducering mha av stegsvar +HISTORY_MSG_88;Tröskelvärde för punktbrusreducering +HISTORY_MSG_89;Brusreducering +HISTORY_MSG_90;Brusreducering - luminans +HISTORY_MSG_91;Brusreducering - krominans +HISTORY_MSG_92;Brusreducering - gamma +HISTORY_MSG_93;Kontrast genom detaljnivåvärden +HISTORY_MSG_94;Kontrast genom detaljnivåer +HISTORY_MSG_95;Mättnad +HISTORY_MSG_96;'a'-kurvan +HISTORY_MSG_97;'b'-kurvan +HISTORY_MSG_98;Demozaicing +HISTORY_MSG_99;Förbehandling +HISTORY_MSG_100;Mättnad, RGB +HISTORY_MSG_101;HSV EQ - Nyans +HISTORY_MSG_102;HSV EQ - Mättnad +HISTORY_MSG_103;HSV EQ - Värde +HISTORY_MSG_104;HSV Equalizer +HISTORY_MSG_105;Reducering av överstrålning +HISTORY_MSG_106;Radie för reducering av överstrålning +HISTORY_MSG_107;Tröskelvärde för reducering av överstrålning +HISTORY_MSG_108;Storleksförändring på avgränsad yta +HISTORY_MSG_109;Storleksförändring tillämpas på +HISTORY_MSG_110;Storleksförändring tillämpas på +HISTORY_MSG_111;Undvik att färgen klipper +HISTORY_MSG_112;Mättnadsbegränsare +HISTORY_MSG_113;Mättnadsgräns +HISTORY_MSG_114;Antal DCB-iterationer +HISTORY_MSG_115;Falska färger iterationer +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önbalanseringsgräns +HISTORY_MSG_121;Automatisk CA-reducering +HISTORY_MSG_122;Automatisk svartbild +HISTORY_MSG_123;Svartbildsfil +HISTORY_MSG_124;Linjär exponeringskompensering +HISTORY_MSG_125;Exponeringskorrigering med bevarande högdagrar +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, krominans +HISTORY_MSG_133;Gamma +HISTORY_MSG_134;Gammaposition +HISTORY_MSG_135;Gamma, fri +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å grön tillsammans +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 efter 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;Styrka +HISTORY_MSG_159;Stoppa vid kanter. +HISTORY_MSG_160;Skala +HISTORY_MSG_163;RGB-kurvor - R +HISTORY_MSG_164;RGB-kurvor - G +HISTORY_MSG_165;RGB-kurvor - B +HISTORY_MSG_166;Neutrala nivåer +HISTORY_NEWSNAPSHOTAS;Som... +HISTORY_NEWSNAPSHOT;Nytt +HISTORY_NEWSSDIALOGLABEL;Namn på bokmärket: +HISTORY_NEWSSDIALOGTITLE;Lägg till nytt bokmärke +HISTORY_SETTO;Ställ in till +HISTORY_SNAPSHOTS;Bokmärken +HISTORY_SNAPSHOT;Bokmärke +ICMPANEL_FILEDLGFILTERANY;Vilka filer som helst +ICMPANEL_FILEDLGFILTERICM;ICC profilfiler +ICMPANEL_GAMMABEFOREINPUT;Profilapplicerad gamma +ICMPANEL_INPUTCAMERA;Kameraval +ICMPANEL_INPUTCUSTOM;Egen +ICMPANEL_INPUTDLGLABEL;Välj inmatnings ICC-profil... +ICMPANEL_INPUTEMBEDDED;Använd inbäddad, om möjligt +ICMPANEL_INPUTPROFILE;Inmatningsprofil +ICMPANEL_NOICM;Ingen ICM: sRGB-utmatning +ICMPANEL_OUTPUTDLGLABEL;Välj utmatnings ICC-profil... +ICMPANEL_OUTPUTPROFILE;Utmatningsprofil +ICMPANEL_SAVEREFERENCE;Spara referensbild för profilering +ICMPANEL_WORKINGPROFILE;Färgrymd +IMAGEAREA_DETAILVIEW;Detalj +IPTCPANEL_AUTHORHINT;Namn på skaparen, t ex skribenten, fotografen eller den grafiska artisten (by-line) +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 eller redigera eller korrigera bilden +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, inte 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_EXIT;Avsluta +MAIN_BUTTON_FULLSCREEN;Helskärm +MAIN_BUTTON_PREFERENCES;Inställningar +MAIN_BUTTON_PUTTOQUEUE;Behandla +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Lägg till nuvarande bild i behandlingskön. Kortkommando: Ctrl+Q +MAIN_BUTTON_QUEUE;Placera i behandlingskön +MAIN_BUTTON_SAVEAS;Som... +MAIN_BUTTON_SAVE;Spara +MAIN_BUTTON_SAVE_TOOLTIP;Spara nuvarande bild. Kortkommando: Ctrl+S +MAIN_BUTTON_SENDTOEDITOR;Redigera +MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Redigera nuvarande bild i externt bildredigeringsprogram. Kortkommando: Ctrl+E +MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Visa/dölj alla sidopaneler m +MAIN_BUTTON_UNFULLSCREEN;Avsluta helskärm +MAIN_FRAME_BATCHQUEUE;Batchkö +MAIN_FRAME_BATCHQUEUE_TOOLTIP; Batchkö Ctrl-F3 +MAIN_FRAME_EDITOR;Redigerfönster +MAIN_FRAME_EDITOR;Redigering +MAIN_FRAME_EDITOR_TOOLTIP; Redigeringsvy Ctrl-F4 +MAIN_FRAME_FILEBROWSER;Filhanterare +MAIN_FRAME_FILEBROWSER_TOOLTIP; Filhanteraren Ctrl-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;Filsparningsfel +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_ERRORDURINGIMAGESAVING;Fel uppstod när bilden sparades +MAIN_MSG_EXITJOBSINQUEUEINFO;Obehandlade bilder i behandlingskön kommer att gå förlorade om programmet stängs av. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Är du säker på att du vill avsluta? Det finns obehandlade bilder i behandlingskön. +MAIN_MSG_IMAGEUNPROCESSED;Det här kommandot kräver att alla valda bilder behandlas i kön först. +MAIN_MSG_JOBSINQUEUE;Arbete(n) i kö +MAIN_MSG_NAVIGATOR;Översikt +MAIN_MSG_PLACES;Platser +MAIN_MSG_QOVERWRITE;Vill du skriva över den? +MAIN_TAB_BASIC;Grund +MAIN_TAB_COLOR;Färger +MAIN_TAB_COLOR_TOOLTIP;Alt-c +MAIN_TAB_DETAIL;Detaljer +MAIN_TAB_DETAIL_TOOLTIP;Alt-d +MAIN_TAB_DEVELOP;Framkalla +MAIN_TAB_EXIF;EXIF +MAIN_TAB_EXPORT; Export +MAIN_TAB_EXPOSURE;Exponering +MAIN_TAB_EXPOSURE_TOOLTIP;Alt-e +MAIN_TAB_FILTER;Filter +MAIN_TAB_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_METADATA_TOOLTIP;Alt-m +MAIN_TAB_RAW;Råbild +MAIN_TAB_RAW_TOOLTIP;Alt-r +MAIN_TAB_TAGGING;Etiketter +MAIN_TAB_TRANSFORM;Omvandla +MAIN_TAB_TRANSFORM_TOOLTIP;Alt-t +MAIN_TOGGLE_BEFORE_AFTER;B|A +MAIN_TOOLTIP_HIDEFP;Visa/göm den nedre panelen. Kortkommando: F +MAIN_TOOLTIP_HIDEHP;Visa/göm den vänstra panelen. Kortkommando: H +MAIN_TOOLTIP_INDCLIPPEDH;Markerad högdagerindikation +MAIN_TOOLTIP_INDCLIPPEDS;Markerad skuggindikation +MAIN_TOOLTIP_PREFERENCES;Ställ in inställningar +MAIN_TOOLTIP_PREVIEWB;Förhandsgranska den blå kanalen.\nGenväg: b +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 +MAIN_TOOLTIP_SAVEAS;Spara bilden till en vald katalog +MAIN_TOOLTIP_SAVE;Spara bilden till standardkatalogen +MAIN_TOOLTIP_SHOWHIDELP1;Visa/dölj vänstra panelen H +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. Kortkommando: 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_NA;x = -, y = - +PARTIALPASTE_BASICGROUP;Grundläggande inställningar +PARTIALPASTE_CACORRECTION;Reducera kromatiska abberationer +PARTIALPASTE_CHANNELMIXER;Kanalmixer +PARTIALPASTE_COARSETRANS;90-graders rotering +PARTIALPASTE_COLORBOOST;Förstärk färger +PARTIALPASTE_COLORDENOISE;Reducera färgbrus +PARTIALPASTE_COLORGROUP;Färgrelaterade inställningar +PARTIALPASTE_COLORMIXER;Färgmixer +PARTIALPASTE_COLORSHIFT;Färgskift +PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto fill +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 processprofiler +PARTIALPASTE_DIRPYRDENOISE;Brusreducering +PARTIALPASTE_DIRPYREQUALIZER;Kontrast genom detaljnivåer +PARTIALPASTE_DISTORTION;Distortionsrättning +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_HLRECONSTRUCTION;Högdageråterställning +PARTIALPASTE_HLRECOVERYAMOUNT;Högdageråterställningsmängd +PARTIALPASTE_HLRECOVERYTHRESHOLD;Högdageråterställning, tröskelvärde +PARTIALPASTE_HLRECOVERY;Högdageråterställning +PARTIALPASTE_HSVEQUALIZER;HSV-equalizer +PARTIALPASTE_ICMGAMMA;Gamma ut +PARTIALPASTE_ICMSETTINGS;ICM-inställningar +PARTIALPASTE_IMPULSEDENOISE;Brusreducering mha stegsvar +PARTIALPASTE_IPTCINFO;IPTC info +PARTIALPASTE_LABCURVE;Labkurva +PARTIALPASTE_LENSGROUP;Objektivrelaterade inställningar +PARTIALPASTE_LUMACURVE;Luminanskurva +PARTIALPASTE_LUMADENOISE;Reducera luminansbrus +PARTIALPASTE_LUMINANCEGROUP;Luminansrelaterade inställningar +PARTIALPASTE_METAICMGROUP;Metadata/ICM inställningar +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 +PARTIALPASTE_RAWCACORR_CABLUE;Blå +PARTIALPASTE_RAWCACORR_CARED;Röd +PARTIALPASTE_RAWEXPOS_BLACK;Svärta +PARTIALPASTE_RAWEXPOS_LINEAR;Linjär korrigeringsfaktor +PARTIALPASTE_RAWEXPOS_PRESER;Korrigering av högdagrar(EV) +PARTIALPASTE_RAWGROUP;Råbildsinställningar +PARTIALPASTE_RAW_ALLENHANCE;Applicera reducering av artefakter och brus efter demosaicing +PARTIALPASTE_RAW_DCBENHANCE;Applicera DCB-förbättringssteg +PARTIALPASTE_RAW_DCBITERATIONS;Antal DCB-iterationer +PARTIALPASTE_RAW_DMETHOD;Metodi för demosaicing +PARTIALPASTE_RAW_FALSECOLOR;Falskt färgbortträngningssteg +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 +PARTIALPASTE_SHARPENMICRO;Mikrokontrast +PARTIALPASTE_VIBRANCE;Lyster +PARTIALPASTE_VIGNETTING;Reducera vinjettering +PARTIALPASTE_WAVELETEQUALIZER;Waveletequalizer +PARTIALPASTE_WHITEBALANCE;Vitbalans +PREFERENCES_ADD;Lägg till +PREFERENCES_APPLNEXTSTARTUP;Ändras vid nästa uppstart +PREFERENCES_AUTOMONPROFILE;Använd operativsystemets skärmprofil +PREFERENCES_BATCH_PROCESSING;Batchbehandling +PREFERENCES_BEHAVIOR;Uppträdande +PREFERENCES_BLINKCLIPPED;Blinka markerade områden +PREFERENCES_CACHECLEARALL;Återställ alla +PREFERENCES_CACHECLEARPROFILES;Återställ profiler +PREFERENCES_CACHECLEARTHUMBS;Ta bort cachade miniatyrbilder +PREFERENCES_CACHEFORMAT1;Proprietär (snabbare och med bättre kvalitet) +PREFERENCES_CACHEFORMAT2;JPEG (tar mindre plats) +PREFERENCES_CACHEMAXENTRIES;Maximalt antal cachefiler +PREFERENCES_CACHEOPTS;Cacheinställningar +PREFERENCES_CACHESTRAT1;Föredra hastighet framför låg minnesanvändning +PREFERENCES_CACHESTRAT2;Föredra låg minnesanvändning framför hastighet +PREFERENCES_CACHESTRAT;Cachestrategi +PREFERENCES_CACHETHUMBFORM;Miniatyrbildens format i cachen +PREFERENCES_CACHETHUMBHEIGHT;Maximal storlek på miniatyrbilderna +PREFERENCES_CLEARDLG_LINE1;Rensa cache +PREFERENCES_CLEARDLG_LINE2;Det här tar kanske ett par sekunder... +PREFERENCES_CLEARDLG_TITLE;Var vänlig vänta +PREFERENCES_CLIPPINGIND;Markeringsindikation +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 Raw/JPG] [Sökväg till standardprofil] [f-nr] [exponering i sek] [brännvidd i mm] [ISO] [Objektiv] [Kamera] +PREFERENCES_CUSTPROFBUILDPATH;Exekverbar sökväg +PREFERENCES_CUTOVERLAYBRUSH;Bakgrundsfärg vid beskärning +PREFERENCES_DARKFRAMEFOUND;Hittade +PREFERENCES_DARKFRAMESHOTS;bilder +PREFERENCES_DARKFRAMETEMPLATES;mallar +PREFERENCES_DARKFRAME;Svartbild +PREFERENCES_DATEFORMATFRAME;Datumformat +PREFERENCES_DATEFORMATHINT;Du kan använda följande formatsträngar:\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_DEMOSAICINGALGO;Algoritm för demosaicing +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 på redigeringsvyn +PREFERENCES_EXTERNALEDITOR;Externt bildredigeringsprogram +PREFERENCES_FBROWSEROPTS;Filbläddrarinställningar +PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Filhanterarens 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_FORIMAGE;För bildfiler +PREFERENCES_FORRAW;För råbilder +PREFERENCES_GIMPPATH;Installationskatalog för GIMP +PREFERENCES_GTKTHEME;GTK standard +PREFERENCES_HINT;Tips +PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogrammet till vänster +PREFERENCES_HLTHRESHOLD;Tröskelvärde för högdagrar +PREFERENCES_ICCDIR;Katalog för ICC-profiler +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 oeprativsystemets språkinställning +PREFERENCES_LIVETHUMBNAILS;Alltid uppdaterade miniatyrbilder(långsammare) +PREFERENCES_MENUGROUPEXTPROGS;Gruppen "Öppna med" +PREFERENCES_MENUGROUPFILEOPERATIONS;Gruppera filaktiviteter +PREFERENCES_MENUGROUPLABEL;Gruppera etikettering +PREFERENCES_MENUGROUPPROFILEOPERATIONS;Gruppera profilaktiviteter +PREFERENCES_MENUGROUPRANK;Gruppera ranking +PREFERENCES_MENUOPTIONS;Menyval +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;Flytta de sparade filerna i den valda katalogen +PREFERENCES_OUTDIRFOLDER;Spara till katalog +PREFERENCES_OUTDIRHINT;Du kan använda följande formatsträngar:\n%f, %d1, %d2, %p1, %p2\n\nDe här formatsträngarna 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_OUTDIRTEMPLATEHINT;Du kan använda följande formatsträngar:\n%f, %d1, %d2, %p1, %p2\n\nDe här formatsträngarna 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_SELECTFONT;Välj typsnitt +PREFERENCES_SELECTICCDIRDLG;Välj ICC-profil katalog... +PREFERENCES_SELECTLANG;Välj språk +PREFERENCES_SELECTMONITORPROFDLG;Välj ICC-profil för skärmen... +PREFERENCES_SELECTTHEME;Välj tema +PREFERENCES_SET;Aktivera +PREFERENCES_SHOWBASICEXIF;Visa grundlig EXIF-information +PREFERENCES_SHOWDATETIME;Visa datum och tid +PREFERENCES_SHOWEXPOSURECOMPENSATION;Lägg till exponeringskompensation +PREFERENCES_SHOWONLYRAW;Visa bara RAW-filer +PREFERENCES_SHOWPROFILESELECTOR;Visa profilväljaren +PREFERENCES_SHTHRESHOLD;Tröskelvärde för skuggor +PREFERENCES_SINGLETABVERTAB;Enkelfliksläge, vertikala flikar +PREFERENCES_SINGLETABVERTAB;En-fliksläge med 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. I Windows kan "SystemDefault", "SystemAsterisk" o.s.v. användas. +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_OUTPUT;Utmatningsinställningar +PREFERENCES_TAB_SOUND;Ljud +PREFERENCES_THUMBSIZE;Miniatyrbildstorlek +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_USESYSTEMTHEME;Använd systemtema +PREFERENCES_WORKFLOW;Arbetsflöde +PROFILEPANEL_COPYPPASTE;Parametrar att kopiera +PROFILEPANEL_FILEDLGFILTERANY;Vilka filer som helst +PROFILEPANEL_FILEDLGFILTERPP;Efterbehandlingsprofiler +PROFILEPANEL_LABEL;Efterbehandlingsprofiler +PROFILEPANEL_LOADDLGLABEL;Ladda efterbehandlingsparametrar... +PROFILEPANEL_LOADPPASTE;Parametrar att ladda +PROFILEPANEL_PASTEPPASTE;Parametrar att klistra in +PROFILEPANEL_PCUSTOM;Egen +PROFILEPANEL_PFILE;Från fil +PROFILEPANEL_PLASTPHOTO;Senaste foto +PROFILEPANEL_PLASTSAVED;Senast sparad +PROFILEPANEL_PROFILE;Profil +PROFILEPANEL_SAVEDLGLABEL;Spara efterbehandlingsparametrar... +PROFILEPANEL_SAVEPPASTE;Parametrar att spara +PROFILEPANEL_TOOLTIPCOPY;Kopiera nuvarande profil till klippbordet +PROFILEPANEL_TOOLTIPLOAD;Ladda profil +PROFILEPANEL_TOOLTIPPASTE; Klistra in profil från klippbordet +PROFILEPANEL_TOOLTIPSAVE;Spara nuvarande profil +PROGRESSBAR_BADPIXELS;Dåliga pixlar... +PROGRESSBAR_CACORRECTION;Reducera kromatiska abberationer... +PROGRESSBAR_DARKFRAME;Mörkbild... +PROGRESSBAR_DECODING;Avkodar råbild... +PROGRESSBAR_DEMOSAICING;Demosaicing... +PROGRESSBAR_GREENEQUIL;Grönbalansera... +PROGRESSBAR_LINEDENOISE;Brusreducera linjärt... +PROGRESSBAR_LOADINGTHUMBS;Laddar miniatyrbilder... +PROGRESSBAR_LOADING;Laddar bild... +PROGRESSBAR_LOADJPEG;Laddar JPEG-fil... +PROGRESSBAR_LOADPNG;Laddar PNG-fil... +PROGRESSBAR_LOADTIFF;Laddar TIFF-fil... +PROGRESSBAR_PROCESSING;Bearbetar bild... +PROGRESSBAR_READY;Klar +PROGRESSBAR_SAVEJPEG;Sparar JPEG-fil... +PROGRESSBAR_SAVEPNG;Sparar PNG-fil... +PROGRESSBAR_SAVETIFF;Sparar TIFF-fil... +PROGRESSDLG_LOADING;Laddar bilden... +PROGRESSDLG_PROCESSING;Bearbetar bilden... +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profilen har ändrats i filhanteraren +PROGRESSDLG_SAVING;Sparar fil... +QINFO_FOCALLENGTH;Brännvidd +QINFO_ISO;ISO +QINFO_LENS;Objektiv +QINFO_NOEXIF;EXIF-information ej tillgänglig. +SAVEDLG_AUTOSUFFIX;Lägg automatiskt till en ändelse om filnamnet redan existerar +SAVEDLG_FILEFORMAT;Filformat +SAVEDLG_JPEGQUAL;JPEG-kvalitet +SAVEDLG_JPGFILTER;JPEG-filer +SAVEDLG_PNGCOMPR;PNG-komprimering +SAVEDLG_PNGFILTER;PNG-filer +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_TIFFFILTER;TIFF-filer +SAVEDLG_TIFFUNCOMPRESSED;Okomprimerad TIFF +TOOLBAR_TOOLTIP_CROP;Välj beskärningsområde. Kortkommando: C +TOOLBAR_TOOLTIP_HAND;Handverktyg. Kortkommando: N +TOOLBAR_TOOLTIP_STRAIGHTEN;Räta upp. Kortkommando: S +TOOLBAR_TOOLTIP_WB;Egen vitbalans. Kortkommando: W +TP_CACORRECTION_BLUE;Blå +TP_CACORRECTION_LABEL;Reducera kromatiska abberationer +TP_CACORRECTION_RED;Röd +TP_CHMIXER_BLUE;Blå +TP_CHMIXER_GREEN;Grön +TP_CHMIXER_LABEL;Kanalmixer +TP_CHMIXER_RED;Röd +TP_CHROMATABERR_LABEL;Kromatiska abberationer +TP_COARSETRAF_DEGREE;grad: +TP_COARSETRAF_TOOLTIP_HFLIP;Vänd horisontellt +TP_COARSETRAF_TOOLTIP_ROTLEFT;Rotera åt vänster +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotera åt höger +TP_COARSETRAF_TOOLTIP_VFLIP;Vänd vertikalt +TP_COLORBOOST_ACHANNEL;Kanal "a" +TP_COLORBOOST_AMOUNT;Mängd +TP_COLORBOOST_AVOIDCOLORCLIP;Undvik att färgen klipper +TP_COLORBOOST_BCHANNEL;Kanal "b" +TP_COLORBOOST_CHANNEL;Kanal +TP_COLORBOOST_CHSEPARATE;Separat +TP_COLORBOOST_ENABLESATLIMITER;Mättnadsbegränsning +TP_COLORBOOST_LABEL;Färgförstärkning +TP_COLORBOOST_SATLIMIT;Mättnadsgräns +TP_COLORDENOISE_EDGESENSITIVE;Kantkänslighet +TP_COLORDENOISE_EDGETOLERANCE;Kanttolerans +TP_COLORDENOISE_LABEL;Färgbrusreducering +TP_COLORDENOISE_RADIUS;Radie +TP_COLORSHIFT_BLUEYELLOW;Blå-Gul +TP_COLORSHIFT_GREENMAGENTA;Grön-Magenta +TP_COLORSHIFT_LABEL;Färgskiftningar +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;Fast proportion +TP_CROP_GTDIAGONALS;Diagonalregeln +TP_CROP_GTEPASSPORT;Biometriskt pass +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 +TP_CROP_LABEL;Beskär +TP_CROP_PPI;PPI= +TP_CROP_SELECTCROP;Välj beskärningsområde +TP_CROP_W;B +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_DETAIL_AMOUNT;Mängd +TP_DIRPYRDENOISE_CHROMA;Krominans +TP_DIRPYRDENOISE_GAMMA;Gamma +TP_DIRPYRDENOISE_LABEL;Brusreducering +TP_DIRPYRDENOISE_LUMA;Luminans +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_SCALE;Skala +TP_EPD_STRENGTH;Styrka +TP_EQUALIZER_CONTRAST_MINUS;Minska kontrasten +TP_EQUALIZER_CONTRAST_PLUS;Öka kontrasten +TP_EQUALIZER_FINEST;Finast +TP_EQUALIZER_LABEL;Waveletequalizer +TP_EQUALIZER_LARGEST;Grövst +TP_EQUALIZER_NEUTRAL;Neutral +TP_EXPOSCORR_LABEL;Vitpunktskorrigering, råbild +TP_EXPOSURE_AUTOLEVELS;Autonivåer +TP_EXPOSURE_BLACKLEVEL;Svärta +TP_EXPOSURE_BRIGHTNESS;Intensitet +TP_EXPOSURE_CLIP;Klippnivå +TP_EXPOSURE_CLIP_TIP;Andelen pixlar som ska klippas när auto-nivå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_CURVEEDITOR;Tonkurva +TP_EXPOSURE_EXPCOMP;Exponeringskompensation +TP_EXPOSURE_LABEL;Exponering +TP_EXPOSURE_SATURATION;Mättnad +TP_EXPO_AFTER; Efter interpolation (före RGB-konvertering) +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_COMMENT;(utprofilen inaktiverad förutom "default") +TP_GAMMA_CURV;gamma +TP_GAMMA_FREE;Obunden gamma +TP_GAMMA_OUTPUT;Gamma ut +TP_GAMMA_SLOP;lutning(linjär) +TP_HLREC_BLEND;Blanda +TP_HLREC_CIELAB;CIELab mix +TP_HLREC_COLOR;Färgspridning +TP_HLREC_LABEL;Högdageråterställning +TP_HLREC_LUMINANCE;Bättring av luminans +TP_HLREC_METHOD;Metod: +TP_HSVEQUALIZER1;Röd +TP_HSVEQUALIZER2;Orange +TP_HSVEQUALIZER3;Gul +TP_HSVEQUALIZER4;Grön +TP_HSVEQUALIZER5;Vatten +TP_HSVEQUALIZER6;Blå +TP_HSVEQUALIZER7;Lila +TP_HSVEQUALIZER8;Magenta +TP_HSVEQUALIZER_CHANNEL;HSV-kanal +TP_HSVEQUALIZER_HUE;Nyans +TP_HSVEQUALIZER_LABEL;HSV-equalizer +TP_HSVEQUALIZER_NEUTRAL;Neutral +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_FILEDLGFILTERANY;Vilka filer som helst +TP_ICM_FILEDLGFILTERICM;ICC-profiler +TP_ICM_GAMMABEFOREINPUT;Profilapplicerad gamma +TP_ICM_INPUTCAMERAICC;Kamerastandard eller ICC +TP_ICM_INPUTCAMERA;Kameraval +TP_ICM_INPUTCAMERA_TOOLTIP;Använd enkel färgmatris från dcraw, förbättrad version från RawTherapee (vilken som är tillgänglig baserad på kameramodell) eller inbäddad från DNG. +TP_ICM_INPUTCUSTOM;Egen +TP_ICM_INPUTCUSTOM_TOOLTIP;Välj DCP/ICC-färgprofil för kameran. +TP_ICM_INPUTDLGLABEL;Välj inmatnings ICC-profil... +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 infärgprofil alls. Används bara i specialfall. +TP_ICM_INPUTPROFILE;Inmatningsprofil +TP_ICM_LABEL;ICM +TP_ICM_NOICM;Ingen ICM: sRGB-utmatning +TP_ICM_OUTPUTDLGLABEL;Välj utmatnings ICC-profil... +TP_ICM_OUTPUTPROFILE;Utmatningsprofil +TP_ICM_PREFERREDPROFILE;Föredragen DCP profil +TP_ICM_PREFERREDPROFILE_1;Dagsljus +TP_ICM_PREFERREDPROFILE_2;Glödlampa +TP_ICM_PREFERREDPROFILE_3;Lysrör +TP_ICM_PREFERREDPROFILE_4;Blixt +TP_ICM_SAVEREFERENCE;Spara referensbild för profilering +TP_ICM_WORKINGPROFILE;Färgrymd +TP_IMPULSEDENOISE_LABEL;Brusreducering mha av stegsvar +TP_IMPULSEDENOISE_THRESH;Tröskelvärde +TP_LABCURVE_AVOIDCOLORCLIP;Undvik att färgen klipper +TP_LABCURVE_BRIGHTNESS;Intensitet +TP_LABCURVE_CONTRAST;Kontrast +TP_LABCURVE_CURVEEDITOR;Luminanskurva +TP_LABCURVE_ENABLESATLIMITER;Slå på mättnadsbegränsare +TP_LABCURVE_LABEL;Labkurvor +TP_LABCURVE_SATLIMIT;Mättnadsbegränsning +TP_LABCURVE_SATURATION;Mättnad +TP_LENSGEOM_AUTOCROP;Autobeskärning +TP_LENSGEOM_FILL;Fyll automatiskt +TP_LENSGEOM_LABEL;Geometri- och distorsionskorrigering +TP_LENSPROFILE_FILEDLGFILTERLCP;Objektivkorrigeringsfil +TP_LENSPROFILE_LABEL;Objektivkorrigeringsprofil +TP_LENSPROFILE_USECA;Använd korrigering för kromatiska abberationer +TP_LENSPROFILE_USEDIST;Använd korrigering för distorsion +TP_LENSPROFILE_USEVIGN;Använd korrigering för vinjettering +TP_LUMACURVE_BLACKLEVEL;Svärta +TP_LUMACURVE_BRIGHTNESS;Intensitet +TP_LUMACURVE_COMPRHIGHLIGHTS;Högdageråterställning +TP_LUMACURVE_COMPRSHADOWS;Skuggåterställning +TP_LUMACURVE_CONTRAST;Kontrast +TP_LUMACURVE_CURVEEDITOR;Luminanskurva +TP_LUMACURVE_LABEL;Luminanskurva +TP_LUMADENOISE_EDGETOLERANCE;Kanttolerans +TP_LUMADENOISE_LABEL;Reducering av luminansbrus +TP_LUMADENOISE_RADIUS;Radie +TP_NEUTRAL;Neutral +TP_NEUTRAL_TIP;Återställ exponeringskontrollerna till nollvärden +TP_PERSPECTIVE_HORIZONTAL;Horisontell +TP_PERSPECTIVE_LABEL;Perspektiv +TP_PERSPECTIVE_VERTICAL;Vertikal +TP_PREPROCESS_GREENEQUIL;Grönbalansering +TP_PREPROCESS_HOTDEADPIXFILT;Applicera het- och dödpixelfiltrering +TP_PREPROCESS_HOTDEADPIXTHRESH;Tröskelvärde för het- eller dödpixelavkänning +TP_PREPROCESS_LABEL;Förbehandling +TP_PREPROCESS_LINEDENOISE;Linjärt brusfilter +TP_PREPROCESS_NO_FOUND;Inga hittade +TP_RAWCACORR_AUTO;Reducera 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;Linjär korrigeringsfaktor +TP_RAWEXPOS_PRESER;Bevara högdagerkorrigering (EV) +TP_RAWEXPOS_TWOGREEN;Två gröna tillsammans +TP_RAW_ALLENHANCE;Applicera reducering av artefakter och brus efter demosaicing +TP_RAW_DCBENHANCE;Applicera DCB-förbättringssteg +TP_RAW_DCBITERATIONS;Antal DCB-iterationer +TP_RAW_DMETHODBATCH;Batch +TP_RAW_DMETHOD;Metod +TP_RAW_FALSECOLOR;Falskt färgbortträngningssteg +TP_RAW_LABEL;Demosaicing +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_DOWNSCALEB;Nedsampla (Bättre) +TP_RESIZE_DOWNSCALEF;Skala ned (Snabbare) +TP_RESIZE_FITBOX;Begränsad yta +TP_RESIZE_FULLIMAGE;Hela bilden +TP_RESIZE_FULLSIZE;Full bildstorlek: +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_RED;R +TP_ROTATE_AUTOCROP;Autobeskär +TP_ROTATE_DEGREE;Antal grader +TP_ROTATE_FILL;Fyll +TP_ROTATE_LABEL;Räta upp +TP_ROTATE_SELECTLINE;Välj rak linje +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_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_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_LABEL;Lyster +TP_VIBRANCE_PASTELS;Pastellfärger +TP_VIBRANCE_PROTECTSKINS;Skydda hudfärger +TP_VIBRANCE_PSTHRESHOLD;Tröskelvärde för pastell- eller mättnadstoner +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;Mängd +TP_WBALANCE_AUTO;Auto +TP_WBALANCE_CAMERA;Kamera +TP_WBALANCE_CLOUDY;Molnigt +TP_WBALANCE_CUSTOM;Egen +TP_WBALANCE_DAYLIGHT;Dagsljus (soligt) +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 (vendor) +TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) +TP_WBALANCE_SPOTWB;Vitbalansväljare +TP_WBALANCE_TEMPERATURE;Temperatur +TP_WBALANCE_TUNGSTEN;Glödlampa +ZOOMBAR_DETAIL;Lupp +ZOOMBAR_HUGE;Enorm +ZOOMBAR_LARGE;Stor +ZOOMBAR_NORMAL;Normal +ZOOMBAR_PREVIEW;Förhandsvisning +ZOOMBAR_SCALE;Skala +ZOOMBAR_SMALL;Liten +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;Öppna (nytt) detaljfönster. +ZOOMPANEL_ZOOM100;Förstora till 100%. Kortkommando: 1 +ZOOMPANEL_ZOOMFITSCREEN;Passa till skärmen. Kortkommando: F +ZOOMPANEL_ZOOMIN;Förstora. Kortkommando: + +ZOOMPANEL_ZOOMOUT;Förminska. Kortkommando: - + +#00 Swedish +#01 Translated by Emil Ericsson +#02 2008-01-22 +#03 Updated 2010 by Johan Thor. +#04 Updated 2011 by Johan Thor. +#05 Updated 2012-09-09 by Johan Thor. + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!EXPORT_BYPASS_RAW_CCSTEPS;Bypass [raw] False Color Suppression +!EXPORT_BYPASS_RAW_DCB_ENHANCE;Bypass [raw] DCB Enhancement Steps +!EXPORT_BYPASS_RAW_LINENOISE;Bypass [raw] Line Noise Filter +!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. +!FILEBROWSER_EXEC_CPB;Custom Profile Builder +!GENERAL_WARNING;Warning +!HISTOGRAM_TOOLTIP_FULL;Toggle full or scaled histogram +!HISTORY_MSG_161;Reweighting Iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_167;B&W Toning +!HISTORY_MSG_168;'CC' curve +!HISTORY_MSG_169;'CH' curve +!HISTORY_MSG_170;Vibrance - Curve +!HISTORY_MSG_171;'LC' curve +!HISTORY_MSG_172;Restrict 'LC' to Red and Skin Tones +!HISTORY_MSG_173;NR - Luminance Detail +!MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 8 +!MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 0 +!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_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. +!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_EPD;Tone Mapping +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing Profile Saved +!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\nthe 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_CROP_GTFRAME;Frame +!TP_DIRPYRDENOISE_LDETAIL;Luminance Detail +!TP_EPD_LABEL;Tone Mapping +!TP_EPD_REWEIGHTINGITERATES;Reweighting iterates +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggle execution of Auto Levels to automatically set parameter values based on image analysis +!TP_EXPOSURE_TCMODE_FILMLIKE;Film-like +!TP_EXPOSURE_TCMODE_LABEL;Curve mode +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_VALBLENDING;Value channel +!TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profile. These profiles are more precise than simpler matrix ones. Available for some 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_TONECURVE;Use DCP's tone curve +!TP_ICM_TONECURVE_TOOLTIP;Enable to use tone curves that may be contained in DCP profiles. +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid Color Shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space\nand apply Munsell correction +!TP_LABCURVE_BWTONING;B&W Toning +!TP_LABCURVE_BWTONING_TIP;With B&W Toning option enabled, the Lab Chromaticity, CC, CH and LC curves are not in effect.\nToning can be achieved using the a and b curves +!TP_LABCURVE_CHROMATICITY;Chromaticity +!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 the Chromaticity +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to the Hue +!TP_LABCURVE_CURVEEDITOR_LC;LC +!TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminance according to Chromaticity +!TP_LABCURVE_LCREDSK;Restrict LC to Red and Skin Tones +!TP_LABCURVE_LCREDSK_TIP;If enabled, 'LC curve' is limited to Red and skin tones\nIf disabled, applies on all tones +!TP_LABCURVE_RSTPROTECTION;Red and skin oversaturation protection +!TP_LABCURVE_RSTPRO_TOOLTIP;Can be used with the Chromaticity slider and the CC curve. +!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 the Hue +!TP_VIBRANCE_PASTSATTOG;Link pastel and saturated tones +!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 diff --git a/rtdata/languages/Turkish b/rtdata/languages/Turkish new file mode 100644 index 000000000..c696a7245 --- /dev/null +++ b/rtdata/languages/Turkish @@ -0,0 +1,1208 @@ +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_DIALOGLABEL;Exif Filter +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_ARRANGEMENTHINT;Change between vertical/horizontal alignment of thumbnails +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_EXIFFILTERAPPLYHINT;Switch on/off exif filter of the file browser +FILEBROWSER_EXIFFILTERAPPLY;Apply +FILEBROWSER_EXIFFILTERLABEL;Exif Filter +FILEBROWSER_EXIFFILTERSETTINGSHINT;Change settings of the exif filter +FILEBROWSER_EXIFFILTERSETTINGS;Setup +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_POPUPRANK1;Rank 1 +FILEBROWSER_POPUPRANK2;Rank 2 +FILEBROWSER_POPUPRANK3;Rank 3 +FILEBROWSER_POPUPRANK4;Rank 4 +FILEBROWSER_POPUPRANK5;Rank 5 +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_PROCESSINGSETTINGSHINT;Set the file format and output directory +FILEBROWSER_PROCESSINGSETTINGS;Settings +FILEBROWSER_RENAMEDLGLABEL;Rename file +FILEBROWSER_RENAMEDLGMSG;Rename file "%1" to: +FILEBROWSER_SHOWDIRHINT;Show all images of the directory +FILEBROWSER_SHOWQUEUEHINT;Show content of the processing queue +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_LOAD;Yükle +GENERAL_NA;Uygun değil +GENERAL_NO;Hayır +GENERAL_OK;Tamam +GENERAL_PORTRAIT;Dikey +GENERAL_SAVE;Kaydet +GENERAL_YES;Evet +HISTOGRAM_LABEL;Histogram +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_NEWSNAPSHOTAS;... olarak +HISTORY_NEWSNAPSHOT;Yeni şipşak +HISTORY_NEWSSDIALOGLABEL;Şipşak etiketi: +HISTORY_NEWSSDIALOGTITLE;Yeni şipşak ekle +HISTORY_SETTO;Belirle +HISTORY_SNAPSHOTS;Şipşaklar +HISTORY_SNAPSHOT;Şipşak +ICMPANEL_FILEDLGFILTERANY;Bütün dosyalar +ICMPANEL_FILEDLGFILTERICM;ICC profil dosyaları +ICMPANEL_GAMMABEFOREINPUT;Profile applies Gamma +ICMPANEL_INPUTCAMERA;Kamera varsayılanı +ICMPANEL_INPUTCUSTOM;Özel +ICMPANEL_INPUTDLGLABEL;Girdi ICC profilini seç... +ICMPANEL_INPUTEMBEDDED;Mümkün olduğunda gömülü profili kullan +ICMPANEL_INPUTPROFILE;Girdi Profili +ICMPANEL_NOICM;No ICM: sRGB çıktı +ICMPANEL_OUTPUTDLGLABEL;Çıktı ICC profilini seç... +ICMPANEL_OUTPUTPROFILE;Çıktı profili +ICMPANEL_SAVEREFERENCE;Save reference image for profiling +ICMPANEL_WORKINGPROFILE;Çalışma profili +IMAGEAREA_DETAILVIEW;Detay görünümü +IPTCPANEL_AUTHORHINT;Name of the creator of the object, e.g. writer, photographer or graphic artist (By-line). +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_EXIT;Exit +MAIN_BUTTON_PREFERENCES;Seçenekler +MAIN_BUTTON_QUEUE;Put to queue +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_EXITJOBSINQUEUEINFO;Unprocessed images in the queue will be lost on exit. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Are you sure you want to exit? There are unprocessed images waiting in the queue. +MAIN_MSG_JOBSINQUEUE;iş sırada +MAIN_MSG_QOVERWRITE;Üzerine yazmak ister misiniz? +MAIN_TAB_BASIC;Temel +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_ICM;Renk yönetimi +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;Dönüşüm +MAIN_TOOLTIP_HIDEFP;Alt tablayı göster/gizle (dizin ve dosya gezgni, shortcut key: F) +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_PREFERENCES;Seçenekleri belirle +MAIN_TOOLTIP_QINFO;Görüntü hakkında kısa bilgi +MAIN_TOOLTIP_SAVEAS;Görüntüyü seçili klasöre kaydet +MAIN_TOOLTIP_SAVE;Görüntüyü varsayılan klasöre kaydet +PARTIALPASTE_BASICGROUP;Basic settings +PARTIALPASTE_CACORRECTION;C/A correction +PARTIALPASTE_COARSETRANS;90 deg rotation / flipping +PARTIALPASTE_COLORBOOST;Color boost +PARTIALPASTE_COLORDENOISE;Color denoise +PARTIALPASTE_COLORGROUP;Color related settings +PARTIALPASTE_COLORMIXER;Color mixer +PARTIALPASTE_COLORSHIFT;Color shift +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_HLRECOVERY;Highlight recovery +PARTIALPASTE_ICMSETTINGS;ICM settings +PARTIALPASTE_IPTCINFO;IPTC info +PARTIALPASTE_LENSGROUP;Lens related settings +PARTIALPASTE_LUMACURVE;Luminance curve +PARTIALPASTE_LUMADENOISE;Luminance noise reduction +PARTIALPASTE_LUMINANCEGROUP;Luminance related settings +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_CACHESTRAT1;Prefer Speed to Low Memory Consumption +PREFERENCES_CACHESTRAT2;Prefer Low Memory Consumption to Speed +PREFERENCES_CACHESTRAT;Cache Strategy +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_DEMOSAICINGALGO;Demozaikleme algoritması +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_HINT;İpucu +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_LIVETHUMBNAILS;Live Thumbnails (slower) +PREFERENCES_MONITORICC;Ekran profili +PREFERENCES_OUTDIRFOLDERHINT;Put the saved images to the seledted folder +PREFERENCES_OUTDIRFOLDER;Save to folder +PREFERENCES_OUTDIRHINT;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_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_SELECTICCDIRDLG;ICC profil dizinini seç... +PREFERENCES_SELECTLANG;Dil seç +PREFERENCES_SELECTMONITORPROFDLG;Ekrana ait ICC profilini seç... +PREFERENCES_SELECTTHEME;Select theme +PREFERENCES_SHOWBASICEXIF;Temel exif bilgisini göster +PREFERENCES_SHOWDATETIME;Tarih ve saati göster +PREFERENCES_SHOWONLYRAW;Sadece RAW dosyalarını 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 +PREFERENCES_TAB_OUTPUT;Çıktı seçenekleri +PREFERENCES_THUMBSIZE;Küçük-resim boyutu +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_PLASTPHOTO;Son Fotoğraf +PROFILEPANEL_PLASTSAVED;Son kaydedilen +PROFILEPANEL_PROFILE;Profil +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_DECODING;Raw dosyası açılıyor... +PROGRESSBAR_DEMOSAICING;Demozaikleniyor... +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_FOCALLENGTH;Odak uzunluğu +QINFO_ISO;ISO +QINFO_LENS;Lens +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_PNGFILTER;PNG dosyaları +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_OUTPUTDLGLABEL;Çıktı ICC profilini seç... +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_LUMADENOISE_EDGETOLERANCE;Kenar payı +TP_LUMADENOISE_LABEL;Aydınlık gürültüsü azaltma +TP_LUMADENOISE_RADIUS;Çap +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_FULLSIZE;Tam gürüntü boyutu: +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ı +ZOOMBAR_DETAIL;Detay +ZOOMBAR_HUGE;Devasa +ZOOMBAR_LARGE;Büyük +ZOOMBAR_NORMAL;Normal +ZOOMBAR_PREVIEW;Önizleme +ZOOMBAR_SCALE;Ölçek +ZOOMBAR_SMALL;Küçük + +#00 Turkish +#01 2.3.2008 +#02 Oguz + +!!!!!!!!!!!!!!!!!!!!!!!!! +! 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 +!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_SHARPENEDGE;Bypass Edge Sharpening +!EXPORT_BYPASS_SHARPENING;Bypass Sharpening +!EXPORT_BYPASS_SHARPENMICRO;Bypass Microcontrast +!EXPORT_BYPASS_SH_HQ;Bypass Shadow/Highlights (High Quality) +!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 the path text box.\nEnter / Ctrl-Enter (in the File Browser) to browse there;\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_CURRENT_NAME;Current name: +!FILEBROWSER_DARKFRAME;Dark frame +!FILEBROWSER_DELETEDLGMSGINCLPROC;Are you sure you want to delete the selected %1 files including a queue-processed version? +!FILEBROWSER_EXEC_CPB;Custom Profile Builder +!FILEBROWSER_EXTPROGMENU;Open with +!FILEBROWSER_FLATFIELD;Flat Field +!FILEBROWSER_MOVETODARKFDIR;Move to dark frames directory +!FILEBROWSER_MOVETOFLATFIELDDIR;Move to flat fields directory +!FILEBROWSER_NEW_NAME;New name: +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!FILEBROWSER_POPUPCOLORLABEL0;Label: None +!FILEBROWSER_POPUPCOLORLABEL1;Label: Red +!FILEBROWSER_POPUPCOLORLABEL2;Label: Yellow +!FILEBROWSER_POPUPCOLORLABEL3;Label: Green +!FILEBROWSER_POPUPCOLORLABEL4;Label: Blue +!FILEBROWSER_POPUPCOLORLABEL5;Label: Purple +!FILEBROWSER_POPUPCOLORLABEL;Color label +!FILEBROWSER_POPUPCOPYTO;Copy to... +!FILEBROWSER_POPUPFILEOPERATIONS;File Operations +!FILEBROWSER_POPUPMOVETO;Move to... +!FILEBROWSER_POPUPPROCESSFAST;Put to Queue (Fast export) +!FILEBROWSER_POPUPPROFILEOPERATIONS;Processing Profile Operations +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_POPUPREMOVESUBMENU;Remove +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!FILEBROWSER_QUERYHINT;Type a partial filename to search for.\nCtrl-F to focus the Find text box (in the File Browser).\nEnter to commence search. +!FILEBROWSER_QUERYLABEL; Find: +!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 +!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-` +!FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +!FILEBROWSER_USETEMPLATE;Use template: +!GENERAL_AFTER;After +!GENERAL_BEFORE;Before +!GENERAL_FILE;File +!GENERAL_HIGH_QUALITY;High Quality +!GENERAL_NONE;None +!GENERAL_UNCHANGED;(Unchanged) +!GENERAL_WARNING;Warning +!HISTOGRAM_BUTTON_BAR;RGB +!HISTOGRAM_BUTTON_B;B +!HISTOGRAM_BUTTON_G;G +!HISTOGRAM_BUTTON_L;L +!HISTOGRAM_BUTTON_RAW;Raw +!HISTOGRAM_BUTTON_R;R +!HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar\nClick right mouse button on image preview to freeze/unfreeze +!HISTOGRAM_TOOLTIP_FULL;Toggle full or scaled histogram +!HISTOGRAM_TOOLTIP_RAW;Show/Hide raw histogram +!HISTORY_MSG_82;Profile Changed +!HISTORY_MSG_83;High Quality Shadows/Highlights +!HISTORY_MSG_84;Perspective Correction +!HISTORY_MSG_85;Lens Correction Profile +!HISTORY_MSG_86;Wavelet Equalizer +!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 +!HISTORY_MSG_92;NR - Gamma +!HISTORY_MSG_93;Contrast by Detail Levels Value +!HISTORY_MSG_94;Contrast by Detail Levels +!HISTORY_MSG_95;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;RGB Saturation +!HISTORY_MSG_101;HSV EQ -- Hue +!HISTORY_MSG_102;HSV EQ -- Saturation +!HISTORY_MSG_103;HSV EQ -- Value +!HISTORY_MSG_104;HSV Equalizer +!HISTORY_MSG_105;Defringing +!HISTORY_MSG_106;Defringing Radius +!HISTORY_MSG_107;Defringing Threshold +!HISTORY_MSG_108;Highlight Compr. Threshold +!HISTORY_MSG_109;Resize Bounding Box +!HISTORY_MSG_110;Resizing applies o +!HISTORY_MSG_111;Avoid Color Shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;Red and Skin Tones Protection +!HISTORY_MSG_114;DCB Iterations +!HISTORY_MSG_115;False Color Iterations +!HISTORY_MSG_116;Enhanced DCB +!HISTORY_MSG_117;Red CA Correction +!HISTORY_MSG_118;Blue CA Correction +!HISTORY_MSG_119;Line Denoise +!HISTORY_MSG_120;Green Equil. Threshold +!HISTORY_MSG_121;Auto CA +!HISTORY_MSG_122;Auto Dark Frame +!HISTORY_MSG_123;Dark Frame File +!HISTORY_MSG_124;Linear Exp. Correction +!HISTORY_MSG_125;Exp. Correction Preserving HL +!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;Gamma +!HISTORY_MSG_134;Gamma Position +!HISTORY_MSG_135;Gamma Free +!HISTORY_MSG_136;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 Green Together +!HISTORY_MSG_142;Edges Sharpening - Iterations +!HISTORY_MSG_143;Edges Sharpening - Quantity +!HISTORY_MSG_144;Microcontrast - Quantity +!HISTORY_MSG_145;Microcontrast - Uniformity +!HISTORY_MSG_146;Edges Sharpening +!HISTORY_MSG_147;Edges Sharpening - 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;Vibrance - Pastel tones +!HISTORY_MSG_153;Vibrance - Saturated tones +!HISTORY_MSG_154;Vibrance - Protect skin tones +!HISTORY_MSG_155;Vibrance - Avoid color drift +!HISTORY_MSG_156;Vibrance - Link pastel and saturated tones +!HISTORY_MSG_157;Vibrance - Pastel/Saturated threshold +!HISTORY_MSG_158;Strength +!HISTORY_MSG_159;Edge Stopping +!HISTORY_MSG_160;Scale +!HISTORY_MSG_161;Reweighting Iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_163;RGB Curves - R +!HISTORY_MSG_164;RGB Curves - G +!HISTORY_MSG_165;RGB Curves - B +!HISTORY_MSG_166;Neutral Levels +!HISTORY_MSG_167;B&W Toning +!HISTORY_MSG_168;'Cc' curve +!HISTORY_MSG_169;'Ch' curve +!HISTORY_MSG_170;Vibrance - Curve +!MAIN_BUTTON_FULLSCREEN;Fullscreen +!MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Put current image to processing queue.\nShortcut: Ctrl+Q +!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_ERRORDURINGIMAGESAVING;Error during image saving +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue processed first. +!MAIN_MSG_NAVIGATOR;Navigator +!MAIN_MSG_PLACES;Places +!MAIN_TAB_COLOR_TOOLTIP;Shortcut: Alt-C +!MAIN_TAB_DETAIL_TOOLTIP;Shortcut: Alt-D +!MAIN_TAB_EXPORT; 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_TOGGLE_BEFORE_AFTER;B|A +!MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 8 +!MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 0 +!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_CHANNELMIXER;Channel mixer +!PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto fill +!PARTIALPASTE_DARKFRAMEAUTOSELECT;Dark Frame Auto Select +!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;FF Auto Select +!PARTIALPASTE_FLATFIELDBLURRADIUS;FF Blur Radius +!PARTIALPASTE_FLATFIELDBLURTYPE;FF Blur Type +!PARTIALPASTE_FLATFIELDFILE;Flat field (FF) File +!PARTIALPASTE_HLRECONSTRUCTION;Highlight reconstruction +!PARTIALPASTE_HLRECOVERYAMOUNT;Highlight recovery amount +!PARTIALPASTE_HLRECOVERYTHRESHOLD;Highlight recovery threshold +!PARTIALPASTE_HSVEQUALIZER;HSV Equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!PARTIALPASTE_LABCURVE;Lab adjustments +!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 Level +!PARTIALPASTE_RAWEXPOS_LINEAR;Raw white point linear corr. factor +!PARTIALPASTE_RAWEXPOS_PRESER;Raw white point HL preserving corr. (EV) +!PARTIALPASTE_RAWGROUP;Raw settings +!PARTIALPASTE_RAW_ALLENHANCE;Apply post demosaic artifact/noise reduction +!PARTIALPASTE_RAW_DCBENHANCE;Apply DCB enhancement step +!PARTIALPASTE_RAW_DCBITERATIONS;Number of DCB iterations +!PARTIALPASTE_RAW_DMETHOD;Demosaic Method +!PARTIALPASTE_RAW_FALSECOLOR;Demosaic False color suppression steps +!PARTIALPASTE_RGBCURVES;RGB curves +!PARTIALPASTE_SHARPENEDGE;Edges +!PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_VIBRANCE;Vibrance +!PARTIALPASTE_WAVELETEQUALIZER;Wavelet equalizer +!PREFERENCES_ADD;ADD +!PREFERENCES_AUTOMONPROFILE;Automatically use operating system's main monitor color profile +!PREFERENCES_BATCH_PROCESSING;Batch Processing +!PREFERENCES_BEHAVIOR;Behavior +!PREFERENCES_CUSTPROFBUILDHINT;Executable (or script) file called when a new initial processing profile should be generated for an image.\nReceives command line parameters to allow a rules-based processing profile generation:\n[raw/JPG path] [default processing profile path] [f-number] [exposure in secs] [focal length in mm] [ISO] [lens] [camera] +!PREFERENCES_CUSTPROFBUILDPATH;Executable path +!PREFERENCES_CUSTPROFBUILD;Custom Processing Profile Builder +!PREFERENCES_CUTOVERLAYBRUSH;Crop mask color/transparency +!PREFERENCES_DARKFRAMEFOUND;Found +!PREFERENCES_DARKFRAMESHOTS;shots +!PREFERENCES_DARKFRAMETEMPLATES;templates +!PREFERENCES_DARKFRAME;Dark Frame +!PREFERENCES_DATEFORMATFRAME;Date Format +!PREFERENCES_DIRDARKFRAMES;Dark frames directory +!PREFERENCES_EDITORLAYOUT;Editor Layout +!PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar (de-select for low res display) +!PREFERENCES_FLATFIELDFOUND;Found +!PREFERENCES_FLATFIELDSDIR;Flat Fields directory +!PREFERENCES_FLATFIELDSHOTS;shots +!PREFERENCES_FLATFIELDTEMPLATES;templates +!PREFERENCES_FLATFIELD;Flat Field +!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_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). On Windows use "SystemDefault", "SystemAsterisk" etc. for system sounds. +!PREFERENCES_SND_LNGEDITPROCDONE;Editor processing done +!PREFERENCES_SND_TRESHOLDSECS;after secs +!PREFERENCES_SQUAREDETAILWINDOW;Square detail window (faster) +!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_USESYSTEMTHEME; Use system theme +!PREFERENCES_WORKFLOW;Layout +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_SAVEPPASTE;Parameters to save +!PROGRESSBAR_BADPIXELS;Bad pixels... +!PROGRESSBAR_CACORRECTION;CA correction... +!PROGRESSBAR_DARKFRAME;Darkframe... +!PROGRESSBAR_GREENEQUIL;Green equilibrate... +!PROGRESSBAR_LINEDENOISE;Line Denoise... +!PROGRESSBAR_LOADINGTHUMBS;Loading thumbnails... +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing Profile Saved +!PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists +!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\nthe 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_CHROMATABERR_LABEL;Chromatic Aberration +!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_DETAIL_AMOUNT;Amount +!TP_DIRPYRDENOISE_CHROMA;Chrominance +!TP_DIRPYRDENOISE_GAMMA;Gamma +!TP_DIRPYRDENOISE_LABEL;Noise reduction +!TP_DIRPYRDENOISE_LUMA;Luminance +!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_EQUALIZER_CONTRAST_MINUS;Contrast- +!TP_EQUALIZER_CONTRAST_PLUS;Contrast+ +!TP_EQUALIZER_FINEST;finest +!TP_EQUALIZER_LABEL;Wavelet equalizer +!TP_EQUALIZER_LARGEST;coarsest +!TP_EQUALIZER_NEUTRAL;Neutral +!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 +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in auto levels operation +!TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Highlight recovery threshold +!TP_EXPOSURE_SATURATION;Saturation +!TP_EXPO_AFTER; After interpolation (before RGB conversion) +!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_HLREC_BLEND;Blend +!TP_HSVEQUALIZER_CHANNEL;HSV Channel +!TP_HSVEQUALIZER_HUE;H +!TP_HSVEQUALIZER_LABEL;HSV Equalizer +!TP_HSVEQUALIZER_NEUTRAL;Neutral +!TP_HSVEQUALIZER_SAT;S +!TP_HSVEQUALIZER_VAL;V +!TP_ICM_BLENDCMSMATRIX;Blend highlights with matrix +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover blown highlights when using LUT based ICC profiles +!TP_ICM_INPUTCAMERAICC;Auto-matched camera-specific color profile +!TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profile. These profiles are more precise than simpler matrix ones. Available for some 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_PREFERREDPROFILE;Preferred DCP profile +!TP_ICM_PREFERREDPROFILE_1;Daylight +!TP_ICM_PREFERREDPROFILE_2;Tungsten +!TP_ICM_PREFERREDPROFILE_3;Fluorescent +!TP_ICM_PREFERREDPROFILE_4;Flash +!TP_IMPULSEDENOISE_LABEL;Impulse Noise Reduction +!TP_IMPULSEDENOISE_THRESH;Impulse NR Threshold +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid Color Shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space\nand apply Munsell correction +!TP_LABCURVE_BRIGHTNESS;Brightness +!TP_LABCURVE_BWTONING;B&W Toning +!TP_LABCURVE_BWTONING_TIP;With B&W Toning option enabled, the Lab Chromaticity, Cc and Ch curves are not in effect.\nToning can be achieved using the a and b curves +!TP_LABCURVE_CHROMATICITY;Chromaticity +!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 the Chromaticity +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to the Hue +!TP_LABCURVE_LABEL;Lab Adjustments +!TP_LABCURVE_RSTPROTECTION;Red and Skin Tones Protection +!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;Use CA correction +!TP_LENSPROFILE_USEDIST;Use distortion correction +!TP_LENSPROFILE_USEVIGN;Use vignette correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Reset exposure controls to neutral values +!TP_PERSPECTIVE_HORIZONTAL;Horizontal +!TP_PERSPECTIVE_LABEL;Perspective +!TP_PERSPECTIVE_VERTICAL;Vertical +!TP_PREPROCESS_GREENEQUIL;Green equilibration +!TP_PREPROCESS_HOTDEADPIXFILT;Apply hot/dead pixel filter +!TP_PREPROCESS_HOTDEADPIXTHRESH;Hot/dead pixel detection threshold +!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 (leader) +!TP_RAWEXPOS_LINEAR;White Point: Linear corr. factor +!TP_RAWEXPOS_PRESER;White Point: HL preserving corr.(EV) +!TP_RAWEXPOS_TWOGREEN;Two greens together +!TP_RAW_ALLENHANCE;Apply post demosaic artifact/noise reduction +!TP_RAW_DCBENHANCE;Apply DCB enhancement step +!TP_RAW_DCBITERATIONS;Number of DCB iterations +!TP_RAW_LABEL;Demosaicing +!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_RED;R +!TP_SHARPENEDGE_AMOUNT;Quantity +!TP_SHARPENEDGE_LABEL;Edges +!TP_SHARPENEDGE_PASSES;Iterations +!TP_SHARPENEDGE_THREE;Luminance only +!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 the Hue +!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_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 +!ZOOMPANEL_100;(100%) +!ZOOMPANEL_NEWCROPWINDOW;Open (new) detail window +!ZOOMPANEL_ZOOM100;Zoom to 100% 1 +!ZOOMPANEL_ZOOMFITSCREEN;Fit to screen F +!ZOOMPANEL_ZOOMIN;Zoom In + +!ZOOMPANEL_ZOOMOUT;Zoom Out - diff --git a/rtdata/languages/default b/rtdata/languages/default new file mode 100644 index 000000000..bc44c6ab0 --- /dev/null +++ b/rtdata/languages/default @@ -0,0 +1,1175 @@ +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 +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_DIALOGLABEL;Exif Filter +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_SHARPENEDGE;Bypass Edge Sharpening +EXPORT_BYPASS_SHARPENING;Bypass Sharpening +EXPORT_BYPASS_SHARPENMICRO;Bypass Microcontrast +EXPORT_BYPASS_SH_HQ;Bypass Shadow/Highlights (High Quality) +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_ARRANGEMENTHINT;Change between vertical/horizontal alignment of thumbnails +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 the path text box.\nEnter / Ctrl-Enter (in the File Browser) to browse there;\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_EXIFFILTERAPPLYHINT;Switch File Browser Exif Filter on/off +FILEBROWSER_EXIFFILTERAPPLY;Apply +FILEBROWSER_EXIFFILTERLABEL;Exif Filter +FILEBROWSER_EXIFFILTERSETTINGSHINT;Change settings of the Exif Filter +FILEBROWSER_EXIFFILTERSETTINGS;Setup +FILEBROWSER_EXTPROGMENU;Open with +FILEBROWSER_FLATFIELD;Flat Field +FILEBROWSER_MOVETODARKFDIR;Move to dark frames directory +FILEBROWSER_MOVETOFLATFIELDDIR;Move to flat fields directory +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +FILEBROWSER_PARTIALPASTEPROFILE;Paste - partial +FILEBROWSER_PASTEPROFILE;Paste +FILEBROWSER_POPUPCANCELJOB;Cancel job +FILEBROWSER_POPUPCOLORLABEL0;Label: None +FILEBROWSER_POPUPCOLORLABEL1;Label: Red +FILEBROWSER_POPUPCOLORLABEL2;Label: Yellow +FILEBROWSER_POPUPCOLORLABEL3;Label: Green +FILEBROWSER_POPUPCOLORLABEL4;Label: Blue +FILEBROWSER_POPUPCOLORLABEL5;Label: Purple +FILEBROWSER_POPUPCOLORLABEL;Color label +FILEBROWSER_POPUPCOPYTO;Copy to... +FILEBROWSER_POPUPFILEOPERATIONS;File Operations +FILEBROWSER_POPUPMOVEEND;Move to end of Queue +FILEBROWSER_POPUPMOVEHEAD;Move to head of Queue +FILEBROWSER_POPUPMOVETO;Move to... +FILEBROWSER_POPUPOPEN;Open +FILEBROWSER_POPUPPROCESSFAST;Put to Queue (Fast export) +FILEBROWSER_POPUPPROCESS;Put to Queue +FILEBROWSER_POPUPPROFILEOPERATIONS;Processing Profile Operations +FILEBROWSER_POPUPRANK1;Rank 1 * +FILEBROWSER_POPUPRANK2;Rank 2 ** +FILEBROWSER_POPUPRANK3;Rank 3 *** +FILEBROWSER_POPUPRANK4;Rank 4 **** +FILEBROWSER_POPUPRANK5;Rank 5 ***** +FILEBROWSER_POPUPRANK;Rank +FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +FILEBROWSER_POPUPREMOVESUBMENU;Remove +FILEBROWSER_POPUPREMOVE;Delete +FILEBROWSER_POPUPRENAME;Rename +FILEBROWSER_POPUPSELECTALL;Select all +FILEBROWSER_POPUPTRASH;Move to trash +FILEBROWSER_POPUPUNRANK;Unrank +FILEBROWSER_POPUPUNTRASH;Remove from trash +FILEBROWSER_PROCESSINGSETTINGSHINT;Set the file format and output directory +FILEBROWSER_PROCESSINGSETTINGS;Settings +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 (in the File Browser).\nEnter to commence search.\nEscape to clear. +FILEBROWSER_QUERYLABEL; Find: +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 +FILEBROWSER_SHOWQUEUEHINT;Show content of the processing queue +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-` +FILEBROWSER_SHOWUNRANKHINT;Show unranked images.\nShortcut: ` +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_USETEMPLATE;Use template: +FILEBROWSER_ZOOMINHINT;Increase thumbnail size.\nShortcut: + +FILEBROWSER_ZOOMOUTHINT;Decrease thumbnail size.\nShortcut: - +GENERAL_ABOUT;About +GENERAL_AFTER;After +GENERAL_BEFORE;Before +GENERAL_CANCEL;Cancel +GENERAL_DISABLED;Disabled +GENERAL_DISABLE;Disable +GENERAL_ENABLED;Enabled +GENERAL_ENABLE;Enable +GENERAL_FILE;File +GENERAL_HIGH_QUALITY;High quality +GENERAL_LANDSCAPE;Landscape +GENERAL_LOAD;Load +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 +GENERAL_YES;Yes +HISTOGRAM_BUTTON_BAR;RGB +HISTOGRAM_BUTTON_B;B +HISTOGRAM_BUTTON_G;G +HISTOGRAM_BUTTON_L;L +HISTOGRAM_BUTTON_RAW;Raw +HISTOGRAM_BUTTON_R;R +HISTOGRAM_LABEL;Histogram +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_FULL;Toggle full or scaled 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;Brightness +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 Exposure +HISTORY_MSG_13;Exposure Clipping +HISTORY_MSG_14;Luminance Brightness +HISTORY_MSG_15;Luminance 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;Sharpening Radius +HISTORY_MSG_22;Sharpening Amount +HISTORY_MSG_23;Sharpening Threshold +HISTORY_MSG_24;Sharpen only edges +HISTORY_MSG_25;Sharpening Edge Detection Radius +HISTORY_MSG_26;Sharpening Edge Tolerance +HISTORY_MSG_27;Sharpening halo control +HISTORY_MSG_28;Halo Control Amount +HISTORY_MSG_29;Sharpening Method +HISTORY_MSG_30;Deconvolution Radius +HISTORY_MSG_31;Deconvolution Amount +HISTORY_MSG_32;Deconvolution Damping +HISTORY_MSG_33;Deconvolution 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;Color Temperature +HISTORY_MSG_40;White Balance 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;Edge Sensitive Color Denoising +HISTORY_MSG_50;Shadow/Highlight +HISTORY_MSG_51;Highlights +HISTORY_MSG_52;Shadows +HISTORY_MSG_53;Highlight Tonal Width +HISTORY_MSG_54;Shadow Tonal Width +HISTORY_MSG_55;Local Contrast +HISTORY_MSG_56;Shadow/Highlight 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;Lens Distortion Correction +HISTORY_MSG_63;Snapshot Selected +HISTORY_MSG_64;Crop Photo +HISTORY_MSG_65;CA correction +HISTORY_MSG_66;Highlight Recovery +HISTORY_MSG_67;Highlight Recovery Amount +HISTORY_MSG_68;Highlight Recovery Method +HISTORY_MSG_69;Working Color Space +HISTORY_MSG_70;Output Color Space +HISTORY_MSG_71;Input Color Space +HISTORY_MSG_72;Vignetting correction +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 Enabled +HISTORY_MSG_82;Profile Changed +HISTORY_MSG_83;High Quality Shadows/Highlights +HISTORY_MSG_84;Perspective Correction +HISTORY_MSG_85;Lens Correction Profile +HISTORY_MSG_86;Wavelet Equalizer +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 +HISTORY_MSG_92;NR - Gamma +HISTORY_MSG_93;Contrast by Detail Levels Value +HISTORY_MSG_94;Contrast by Detail Levels +HISTORY_MSG_95;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;RGB Saturation +HISTORY_MSG_101;HSV EQ -- Hue +HISTORY_MSG_102;HSV EQ -- Saturation +HISTORY_MSG_103;HSV EQ -- Value +HISTORY_MSG_104;HSV Equalizer +HISTORY_MSG_105;Defringing +HISTORY_MSG_106;Defringing Radius +HISTORY_MSG_107;Defringing Threshold +HISTORY_MSG_108;Highlight Compr. Threshold +HISTORY_MSG_109;Resize Bounding Box +HISTORY_MSG_110;Resizing applies to +HISTORY_MSG_111;Avoid color shift +HISTORY_MSG_112;--unused-- +HISTORY_MSG_113;Red and Skin Tones Protection +HISTORY_MSG_114;DCB Iterations +HISTORY_MSG_115;False Color Iterations +HISTORY_MSG_116;Enhanced DCB +HISTORY_MSG_117;Raw Red CA Correction +HISTORY_MSG_118;Raw Blue CA Correction +HISTORY_MSG_119;Line Denoise +HISTORY_MSG_120;Green Equil. Threshold +HISTORY_MSG_121;Raw Auto CA +HISTORY_MSG_122;Auto Dark Frame +HISTORY_MSG_123;Dark Frame File +HISTORY_MSG_124;Linear Exp. Correction +HISTORY_MSG_125;Exp. Correction Preserving HL +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;Gamma +HISTORY_MSG_134;Gamma Position +HISTORY_MSG_135;Gamma free +HISTORY_MSG_136;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 Green Together +HISTORY_MSG_142;Edges Sharpening - Iterations +HISTORY_MSG_143;Edges Sharpening - Quantity +HISTORY_MSG_144;Microcontrast - Quantity +HISTORY_MSG_145;Microcontrast - Uniformity +HISTORY_MSG_146;Edges Sharpening +HISTORY_MSG_147;Edges Sharpening - 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;Vibrance - Pastel tones +HISTORY_MSG_153;Vibrance - Saturated tones +HISTORY_MSG_154;Vibrance - Protect skin tones +HISTORY_MSG_155;Vibrance - Avoid color shift +HISTORY_MSG_156;Vibrance - Link pastel and saturated tones +HISTORY_MSG_157;Vibrance - Pastel/Saturated threshold +HISTORY_MSG_158;Strength +HISTORY_MSG_159;Edge Stopping +HISTORY_MSG_160;Scale +HISTORY_MSG_161;Reweighting Iterates +HISTORY_MSG_162;Tone Mapping +HISTORY_MSG_163;RGB Curves - R +HISTORY_MSG_164;RGB Curves - G +HISTORY_MSG_165;RGB Curves - B +HISTORY_MSG_166;Neutral Levels +HISTORY_MSG_167;B&W toning +HISTORY_MSG_168;'CC' curve +HISTORY_MSG_169;'CH' curve +HISTORY_MSG_170;Vibrance - Curve +HISTORY_MSG_171;'LC' curve +HISTORY_MSG_172;Restrict LC to red and skin tones +HISTORY_MSG_173;NR - Luminance Detail +HISTORY_NEWSNAPSHOTAS;As... +HISTORY_NEWSNAPSHOT;Add +HISTORY_NEWSSDIALOGLABEL;Label of the snapshot: +HISTORY_NEWSSDIALOGTITLE;Add new snapshot +HISTORY_SETTO;Set to +HISTORY_SNAPSHOTS;Snapshots +HISTORY_SNAPSHOT;Snapshot +ICMPANEL_FILEDLGFILTERANY;Any files +ICMPANEL_FILEDLGFILTERICM;Color profiles +ICMPANEL_GAMMABEFOREINPUT;Color Profile Applies Gamma +ICMPANEL_INPUTCAMERA;Camera Default +ICMPANEL_INPUTCUSTOM;Custom +ICMPANEL_INPUTDLGLABEL;Select Input Color Profile... +ICMPANEL_INPUTEMBEDDED;Use Embedded, if possible +ICMPANEL_INPUTPROFILE;Input Color Profile +ICMPANEL_NOICM;No ICM: sRGB Output +ICMPANEL_OUTPUTDLGLABEL;Select Output Color Profile... +ICMPANEL_OUTPUTPROFILE;Output Color Profile +ICMPANEL_SAVEREFERENCE;Save reference image for profiling +ICMPANEL_WORKINGPROFILE;Working Color Profile +IMAGEAREA_DETAILVIEW;Detail View +IPTCPANEL_AUTHORHINT;Name of the creator of the object, e.g. writer, photographer or graphic artist (By-line). +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_EXIT;Exit +MAIN_BUTTON_FULLSCREEN;Fullscreen +MAIN_BUTTON_PREFERENCES;Preferences +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Put current image to processing queue.\nShortcut: Ctrl+Q +MAIN_BUTTON_QUEUE;Put to Queue +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_ERRORDURINGIMAGESAVING;Error during image saving +MAIN_MSG_EXITJOBSINQUEUEINFO;Unprocessed images in the queue will be lost on exit. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Are you sure you want to exit? There are unprocessed images waiting in the queue. +MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue processed first. +MAIN_MSG_JOBSINQUEUE;job(s) in the queue +MAIN_MSG_NAVIGATOR;Navigator +MAIN_MSG_PLACES;Places +MAIN_MSG_QOVERWRITE;Do you want to overwrite it? +MAIN_TAB_BASIC;Basic +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; Export +MAIN_TAB_EXPOSURE;Exposure +MAIN_TAB_EXPOSURE_TOOLTIP;Shortcut: Alt-E +MAIN_TAB_FILTER; Filter +MAIN_TAB_ICM;ICM +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_TOGGLE_BEFORE_AFTER;B|A +MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 8 +MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 +MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 0 +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_HIDEFP;Show/Hide the bottom panel (directory and file browser).\nShortcut: F +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_PREFERENCES;Set preferences +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_SAVEAS;Save image to a specific folder +MAIN_TOOLTIP_SAVE;Save image to the default folder +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;CA correction +PARTIALPASTE_CHANNELMIXER;Channel mixer +PARTIALPASTE_COARSETRANS;90° rotation / flipping +PARTIALPASTE_COLORBOOST;Color boost +PARTIALPASTE_COLORDENOISE;Color denoise +PARTIALPASTE_COLORGROUP;Color Related Settings +PARTIALPASTE_COLORMIXER;Color mixer +PARTIALPASTE_COLORSHIFT;Color shift +PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto fill +PARTIALPASTE_COMPOSITIONGROUP;Composition Settings +PARTIALPASTE_CROP;Crop +PARTIALPASTE_DARKFRAMEAUTOSELECT;Dark frame auto select +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;FF auto select +PARTIALPASTE_FLATFIELDBLURRADIUS;FF blur radius +PARTIALPASTE_FLATFIELDBLURTYPE;FF blur type +PARTIALPASTE_FLATFIELDFILE;Flat field (FF) File +PARTIALPASTE_HLRECONSTRUCTION;Highlight reconstruction +PARTIALPASTE_HLRECOVERYAMOUNT;Highlight recovery amount +PARTIALPASTE_HLRECOVERYTHRESHOLD;Highlight recovery threshold +PARTIALPASTE_HLRECOVERY;Highlight recovery +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_LUMADENOISE;Luminance noise reduction +PARTIALPASTE_LUMINANCEGROUP;Luminance related settings +PARTIALPASTE_METAICMGROUP;Metadata/Color Management Settings +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 level +PARTIALPASTE_RAWEXPOS_LINEAR;White point linear corr. factor +PARTIALPASTE_RAWEXPOS_PRESER;White point HL preserving corr. (EV) +PARTIALPASTE_RAWGROUP;Raw Settings +PARTIALPASTE_RAW_ALLENHANCE;Apply post demosaic artifact/noise reduction +PARTIALPASTE_RAW_DCBENHANCE;Apply DCB enhancement step +PARTIALPASTE_RAW_DCBITERATIONS;Number of DCB iterations +PARTIALPASTE_RAW_DMETHOD;Demosaic method +PARTIALPASTE_RAW_FALSECOLOR;Demosaic false color suppression 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_WAVELETEQUALIZER;Wavelet equalizer +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_BEHAVIOR;Behavior +PREFERENCES_BLINKCLIPPED;Blink clipped areas +PREFERENCES_CACHECLEARALL;Clear All +PREFERENCES_CACHECLEARPROFILES;Clear Processing 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_CACHESTRAT1;Prefer Speed to Low Memory Consumption +PREFERENCES_CACHESTRAT2;Prefer Low Memory Consumption to Speed +PREFERENCES_CACHESTRAT;Cache Strategy +PREFERENCES_CACHETHUMBFORM;Cache thumbnail format +PREFERENCES_CACHETHUMBHEIGHT;Maximal thumbnail height +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.\nReceives command line parameters to allow a rules-based processing profile generation:\n[raw/JPG path] [default processing profile path] [f-number] [exposure in secs] [focal length in mm] [ISO] [lens] [camera] +PREFERENCES_CUSTPROFBUILDPATH;Executable path +PREFERENCES_CUSTPROFBUILD;Custom Processing Profile Builder +PREFERENCES_CUTOVERLAYBRUSH;Crop mask color/transparency +PREFERENCES_DARKFRAMEFOUND;Found +PREFERENCES_DARKFRAMESHOTS;shots +PREFERENCES_DARKFRAMETEMPLATES;templates +PREFERENCES_DARKFRAME;Dark Frame +PREFERENCES_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_DEMOSAICINGALGO;Demosaicing Algorithm +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_FORIMAGE;For non-raw photos +PREFERENCES_FORRAW;For raw photos +PREFERENCES_GIMPPATH;GIMP installation directory +PREFERENCES_GTKTHEME;GTK default +PREFERENCES_HINT;Hint +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_LIVETHUMBNAILS;Live Thumbnails (slower) +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_OUTDIRHINT;You can use the following formatting strings:\n%f, %d1, %d2, ..., %p1, %p2, ..., %r\n\nThese formatting strings refer to the different parts of the photo's pathname or some attributes of the photo.\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\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_OUTDIRTEMPLATEHINT;You can use the following formatting strings:\n%f, %d1, %d2, ..., %p1, %p2, ..., %r\n\nThese formatting strings refer to the different parts of the photo's pathname or some attributes of the photo.\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\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_SELECTFONT;Select font +PREFERENCES_SELECTICCDIRDLG;Select Color Profile Directory... +PREFERENCES_SELECTLANG;Select language +PREFERENCES_SELECTMONITORPROFDLG;Select Color Profile of the Display... +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_SHOWONLYRAW;Show only raw files +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). On Windows use "SystemDefault", "SystemAsterisk" 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_OUTPUT;Output Options +PREFERENCES_TAB_SOUND;Sounds +PREFERENCES_THUMBSIZE;Thumbnail Size +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_USESYSTEMTHEME;Use system theme +PREFERENCES_WORKFLOW;Layout +PROFILEPANEL_COPYPPASTE;Parameters to copy +PROFILEPANEL_FILEDLGFILTERANY;Any files +PROFILEPANEL_FILEDLGFILTERPP;Processing profiles +PROFILEPANEL_LABEL;Processing Profiles +PROFILEPANEL_LOADDLGLABEL;Load Processing Parameters... +PROFILEPANEL_LOADPPASTE;Parameters to load +PROFILEPANEL_PASTEPPASTE;Parameters to paste +PROFILEPANEL_PCUSTOM;Custom +PROFILEPANEL_PFILE;From file +PROFILEPANEL_PLASTPHOTO;Last Photo +PROFILEPANEL_PLASTSAVED;Last Saved +PROFILEPANEL_PROFILE;Profile +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_BADPIXELS;Bad pixels... +PROGRESSBAR_CACORRECTION;CA correction... +PROGRESSBAR_DARKFRAME;Darkframe... +PROGRESSBAR_DECODING;Decoding raw file... +PROGRESSBAR_DEMOSAICING;Demosaicing... +PROGRESSBAR_GREENEQUIL;Green equilibrating... +PROGRESSBAR_LINEDENOISE;Line denoise... +PROGRESSBAR_LOADINGTHUMBS;Loading thumbnails... +PROGRESSBAR_LOADING;Loading image... +PROGRESSBAR_LOADJPEG;Loading JPEG file... +PROGRESSBAR_LOADPNG;Loading PNG file... +PROGRESSBAR_LOADTIFF;Loading TIFF file... +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... +PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +QINFO_FOCALLENGTH;Focal length +QINFO_ISO;ISO +QINFO_LENS;Lens +QINFO_NOEXIF;Exif data not available. +SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists +SAVEDLG_FILEFORMAT;File format +SAVEDLG_JPEGQUAL;JPEG Quality +SAVEDLG_JPGFILTER;JPEG files +SAVEDLG_PNGCOMPR;PNG Compression +SAVEDLG_PNGFILTER;PNG files +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\nthe 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 +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_CACORRECTION_BLUE;Blue +TP_CACORRECTION_LABEL;CA 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: [ +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotate right.\nShortcut: ] +TP_COARSETRAF_TOOLTIP_VFLIP;Flip vertically +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_CHROMA;Chrominance +TP_DIRPYRDENOISE_GAMMA;Gamma +TP_DIRPYRDENOISE_LABEL;Noise Reduction (raw images only) +TP_DIRPYRDENOISE_LDETAIL;Luminance Detail +TP_DIRPYRDENOISE_LUMA;Luminance +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 +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 +TP_EXPOSURE_BLACKLEVEL;Black +TP_EXPOSURE_BRIGHTNESS;Brightness +TP_EXPOSURE_CLIP;Clip +TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in auto level's operation +TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Highlight Recovery Threshold +TP_EXPOSURE_COMPRHIGHLIGHTS;Highlight Recovery Amount +TP_EXPOSURE_COMPRSHADOWS;Shadow Recovery +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_WEIGHTEDSTD;Weighted Standard +TP_EXPOSURE_TCMODE_STANDARD;Standard +TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Saturation and Value Blending +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_HLREC_BLEND;Blend +TP_HLREC_CIELAB;CIELab Blending +TP_HLREC_COLOR;Color Propagation +TP_HLREC_LABEL;Highlight Reconstruction +TP_HLREC_LUMINANCE;Luminance Recovery +TP_HLREC_METHOD;Method: +TP_HSVEQUALIZER_CHANNEL;HSV Channel +TP_HSVEQUALIZER_HUE;H +TP_HSVEQUALIZER_LABEL;HSV Equalizer +TP_HSVEQUALIZER_NEUTRAL;Neutral +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_FILEDLGFILTERANY;Any files +TP_ICM_FILEDLGFILTERICM;Color profiles +TP_ICM_INPUTCAMERAICC;Auto-matched camera-specific color 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_OUTPUTDLGLABEL;Select Output ICC Profile... +TP_ICM_OUTPUTPROFILE;Output Profile +TP_ICM_PREFERREDPROFILE;Preferred DCP profile +TP_ICM_PREFERREDPROFILE_1;Daylight +TP_ICM_PREFERREDPROFILE_2;Tungsten +TP_ICM_PREFERREDPROFILE_3;Fluorescent +TP_ICM_PREFERREDPROFILE_4;Flash +TP_ICM_SAVEREFERENCE;Save Reference Image for Profiling +TP_ICM_TONECURVE;Use DCP's tone curve +TP_ICM_TONECURVE_TOOLTIP;Enable to use tone curves that may be contained in DCP profiles. +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\nand apply Munsell correction +TP_LABCURVE_RSTPRO_TOOLTIP;Can be used with the Chromaticity slider and the CC curve. +TP_LABCURVE_LCREDSK;Restrict LC to red and skin tones +TP_LABCURVE_LCREDSK_TIP;If enabled, LC Curve (Luminance According to Chromaticity) is limited to red and skin tones\nIf disabled, applies on all tones +TP_LABCURVE_BRIGHTNESS;Brightness +TP_LABCURVE_BWTONING;B&W toning +TP_LABCURVE_BWTONING_TIP;With the B&W toning option enabled, the Lab Chromaticity, CC, CH and LC curves are not in effect.\nToning can be achieved using the a and b curves +TP_LABCURVE_CHROMATICITY;Chromaticity +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 the chromaticity +TP_LABCURVE_CURVEEDITOR_CH;CH +TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to the hue +TP_LABCURVE_CURVEEDITOR_LC;LC +TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminance according to the chromaticity +TP_LABCURVE_LABEL;Lab Adjustments +TP_LABCURVE_RSTPROTECTION;Red and Skin Tones Protection +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_LUMADENOISE_EDGETOLERANCE;Edge Tolerance +TP_LUMADENOISE_LABEL;Luminance Noise Reduction +TP_LUMADENOISE_RADIUS;Radius +TP_NEUTRAL;Neutral +TP_NEUTRAL_TIP;Reset exposure controls to neutral values +TP_PERSPECTIVE_HORIZONTAL;Horizontal +TP_PERSPECTIVE_LABEL;Perspective +TP_PERSPECTIVE_VERTICAL;Vertical +TP_PREPROCESS_GREENEQUIL;Green Equilibration +TP_PREPROCESS_HOTDEADPIXFILT;Hot/Dead pixel filter +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 (leader) +TP_RAWEXPOS_LINEAR;White Point: Linear Corr. Factor +TP_RAWEXPOS_PRESER;White Point: HL Preserving Corr. (EV) +TP_RAWEXPOS_TWOGREEN;Two greens together +TP_RAW_ALLENHANCE;Post-Demosaic Artifact/Noise Reduction +TP_RAW_DCBENHANCE;DCB Enhancement Step +TP_RAW_DCBITERATIONS;Number of DCB Iterations +TP_RAW_DMETHOD;Method +TP_RAW_FALSECOLOR;False Color Suppression Steps +TP_RAW_LABEL;Demosaicing +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_FULLSIZE;Full Image Size: +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_RED;R +TP_ROTATE_DEGREE;Degree +TP_ROTATE_LABEL;Rotate +TP_ROTATE_SELECTLINE;Select Straight Line +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_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_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 the hue +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_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 +ZOOMBAR_DETAIL;Detail +ZOOMBAR_HUGE;Huge +ZOOMBAR_LARGE;Large +ZOOMBAR_NORMAL;Normal +ZOOMBAR_PREVIEW;Preview +ZOOMBAR_SCALE;Scale +ZOOMBAR_SMALL;Small +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;Open (new) detail window +ZOOMPANEL_ZOOM100;Zoom to 100%\nShortcut: 1 +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen\nShortcut: f +ZOOMPANEL_ZOOMIN;Zoom In\nShortcut: + +ZOOMPANEL_ZOOMOUT;Zoom Out\nShortcut: - +#00 default translation file +#01 Developers should add translations to this file and then run the 'generateTranslationDiffs' script to update other locales. This is a Bash script, tested in >=Bash-4.2. diff --git a/rtdata/options/options.lin b/rtdata/options/options.lin new file mode 100644 index 000000000..f40e1685e --- /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=arw;cr2;crf;crw;dng;jpg;jpeg;kdc;mef;mrw;nef;nrw;orf;pef;png;raf;raw;rw2;rwz;sr2;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; + +[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=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..f40e1685e --- /dev/null +++ b/rtdata/options/options.osx @@ -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=arw;cr2;crf;crw;dng;jpg;jpeg;kdc;mef;mrw;nef;nrw;orf;pef;png;raf;raw;rw2;rwz;sr2;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; + +[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=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..ec72b661b --- /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=arw;cr2;crf;crw;dng;jpg;jpeg;kdc;mef;mrw;nef;nrw;orf;pef;png;raf;raw;rw2;rwz;sr2;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; + +[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=Default + +# Default profile name (without extension) to use for standard (8bits) images +#ImgDefault=Neutral diff --git a/rtdata/profiles/BW-1.pp3 b/rtdata/profiles/BW-1.pp3 new file mode 100644 index 000000000..53cf95043 --- /dev/null +++ b/rtdata/profiles/BW-1.pp3 @@ -0,0 +1,235 @@ + +[Version] +AppVersion=4.0.9 +Version=305 + +[General] +Rank=0 +ColorLabel=0 +InTrash=false + +[Exposure] +Auto=true +Clip=0 +Compensation=0 +Brightness=0 +Contrast=20 +Saturation=0 +Black=0 +HighlightCompr=0 +HighlightComprThreshold=33 +ShadowCompr=50 +CurveMode=Standard +Curve=1;0;0;0.04;0.03;0.17684498029510265;0.21732319394192093;0.70232558139534862;0.74883720930232545;1;1; +CurveMode2=Standard +Curve2=0; + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=0 +BWtoning=true +AvoidColorShift=true +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; + +[Sharpening] +Enabled=false +Method=usm +Radius=0.5 +Amount=125 +Threshold=20;80;2000;1200; +OnlyEdges=false +EdgedetectionRadius=1.9 +EdgeTolerance=1800 +HalocontrolEnabled=false +HalocontrolAmount=85 +DeconvRadius=0.75 +DeconvAmount=75 +DeconvDamping=20 +DeconvIterations=30 + +[Vibrance] +Enabled=false +Pastels=50 +Saturated=50 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=true +PastSatTog=true +SkinTonesCurve=0; + +[SharpenEdge] +Enabled=false +Passes=2 +Strength=50 +ThreeChannels=false + +[SharpenMicro] +Enabled=false +Matrix=false +Strength=20 +Uniformity=50 + +[White Balance] +Setting=Camera +Temperature=5745 +Green=1.0 + +[Impulse Denoising] +Enabled=false +Threshold=50 + +[Defringing] +Enabled=false +Radius=2.0 +Threshold=25 + +[Directional Pyramid Denoising] +Enabled=false +Luma=0 +Ldetail=80 +Chroma=15 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.4 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=10 +HighlightTonalWidth=80 +Shadows=10 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=30 + +[Crop] +Enabled=false +X=0 +Y=0 +W=7360 +H=4912 +FixedRatio=false +Ratio=3:2 +Orientation=Landscape +Guide=None + +[Coarse Transformation] +Rotate=0 +HorizontalFlip=false +VerticalFlip=false + +[Common Properties for Transformations] +AutoFill=true + +[Rotation] +Degree=0 + +[Distortion] +Amount=0 + +[LensProfile] +LCPFile= +UseDistortion=true +UseVignette=true +UseCA=false + +[Perspective] +Horizontal=0 +Vertical=0 + +[CACorrection] +Red=0 +Blue=0 + +[Vignetting Correction] +Amount=0 +Radius=50 +Strength=1 +CenterX=0 +CenterY=0 + +[HLRecovery] +Enabled=false +Method=Blend + +[Resize] +Enabled=false +Scale=1 +AppliesTo=Cropped area +Method=Lanczos +DataSpecified=3 +Width=900 +Height=900 + +[Color Management] +InputProfile=(cameraICC) +BlendCMSMatrix=true +WorkingProfile=sRGB +OutputProfile=No ICM: sRGB output +Gammafree=default +Freegamma=false +GammaValue=2.22 +GammaSlope=4.5 + +[Directional Pyramid Equalizer] +Enabled=true +Mult0=3 +Mult1=1 +Mult2=1 +Mult3=1 +Mult4=0.2 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +rCurve=0; +gCurve=0; +bCurve=0; + +[RAW] +DarkFrame= +DarkFrameAuto=false +FlatFieldFile= +FlatFieldAutoSelect=false +FlatFieldBlurRadius=32 +FlatFieldBlurType=Area Flatfield +CA=false +CARed=0 +CABlue=0 +HotDeadPixels=false +HotDeadPixelThresh=40 +LineDenoise=0 +GreenEqThreshold=0 +CcSteps=0 +Method=amaze +DCBIterations=2 +DCBEnhance=false +ALLEnhance=false +PreExposure=1 +PrePreserv=0 +PreBlackzero=0 +PreBlackone=0 +PreBlacktwo=0 +PreBlackthree=0 +PreTwoGreen=true diff --git a/rtdata/profiles/BW-2.pp3 b/rtdata/profiles/BW-2.pp3 new file mode 100644 index 000000000..b3504fe4a --- /dev/null +++ b/rtdata/profiles/BW-2.pp3 @@ -0,0 +1,235 @@ + +[Version] +AppVersion=4.0.9 +Version=305 + +[General] +Rank=0 +ColorLabel=0 +InTrash=false + +[Exposure] +Auto=true +Clip=0.0000 +Compensation=0 +Brightness=0 +Contrast=20 +Saturation=0 +Black=0 +HighlightCompr=0 +HighlightComprThreshold=33 +ShadowCompr=50 +CurveMode=Standard +Curve=1;0;0;0.45754265471370759;0.57906737998843294;1;1; +CurveMode2=Standard +Curve2=0; + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=0 +BWtoning=true +AvoidColorShift=true +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=3;0;0;0.84892086330935235;0.69064748201438808;1;1; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; + +[Sharpening] +Enabled=false +Method=usm +Radius=0.5 +Amount=125 +Threshold=20;80;2000;1200; +OnlyEdges=false +EdgedetectionRadius=1.9 +EdgeTolerance=1800 +HalocontrolEnabled=false +HalocontrolAmount=85 +DeconvRadius=0.75 +DeconvAmount=75 +DeconvDamping=20 +DeconvIterations=30 + +[Vibrance] +Enabled=false +Pastels=50 +Saturated=50 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=true +PastSatTog=true +SkinTonesCurve=0; + +[SharpenEdge] +Enabled=false +Passes=2 +Strength=50 +ThreeChannels=false + +[SharpenMicro] +Enabled=false +Matrix=false +Strength=20 +Uniformity=50 + +[White Balance] +Setting=Camera +Temperature=5745 +Green=1.0 + +[Impulse Denoising] +Enabled=false +Threshold=50 + +[Defringing] +Enabled=false +Radius=2.0 +Threshold=25 + +[Directional Pyramid Denoising] +Enabled=false +Luma=0 +Ldetail=80 +Chroma=15 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.4 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=10 +HighlightTonalWidth=80 +Shadows=10 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=30 + +[Crop] +Enabled=false +X=0 +Y=0 +W=7360 +H=4912 +FixedRatio=false +Ratio=3:2 +Orientation=Landscape +Guide=None + +[Coarse Transformation] +Rotate=0 +HorizontalFlip=false +VerticalFlip=false + +[Common Properties for Transformations] +AutoFill=true + +[Rotation] +Degree=0 + +[Distortion] +Amount=0 + +[LensProfile] +LCPFile= +UseDistortion=true +UseVignette=true +UseCA=false + +[Perspective] +Horizontal=0 +Vertical=0 + +[CACorrection] +Red=0 +Blue=0 + +[Vignetting Correction] +Amount=0 +Radius=50 +Strength=1 +CenterX=0 +CenterY=0 + +[HLRecovery] +Enabled=false +Method=Blend + +[Resize] +Enabled=false +Scale=1 +AppliesTo=Cropped area +Method=Lanczos +DataSpecified=3 +Width=900 +Height=900 + +[Color Management] +InputProfile=(cameraICC) +BlendCMSMatrix=true +WorkingProfile=sRGB +OutputProfile=No ICM: sRGB output +Gammafree=default +Freegamma=false +GammaValue=2.22 +GammaSlope=4.5 + +[Directional Pyramid Equalizer] +Enabled=true +Mult0=3 +Mult1=1 +Mult2=1 +Mult3=1 +Mult4=0.2 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +rCurve=0; +gCurve=0; +bCurve=0; + +[RAW] +DarkFrame= +DarkFrameAuto=false +FlatFieldFile= +FlatFieldAutoSelect=false +FlatFieldBlurRadius=32 +FlatFieldBlurType=Area Flatfield +CA=false +CARed=0 +CABlue=0 +HotDeadPixels=false +HotDeadPixelThresh=40 +LineDenoise=0 +GreenEqThreshold=0 +CcSteps=0 +Method=amaze +DCBIterations=2 +DCBEnhance=false +ALLEnhance=false +PreExposure=1 +PrePreserv=0 +PreBlackzero=0 +PreBlackone=0 +PreBlacktwo=0 +PreBlackthree=0 +PreTwoGreen=true diff --git a/rtdata/profiles/BW-3.pp3 b/rtdata/profiles/BW-3.pp3 new file mode 100644 index 000000000..163e6d558 --- /dev/null +++ b/rtdata/profiles/BW-3.pp3 @@ -0,0 +1,235 @@ + +[Version] +AppVersion=4.0.9 +Version=305 + +[General] +Rank=0 +ColorLabel=0 +InTrash=false + +[Exposure] +Auto=true +Clip=0.0000 +Compensation=0 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=0 +HighlightComprThreshold=33 +ShadowCompr=50 +CurveMode=Standard +Curve=0; +CurveMode2=Standard +Curve2=0; + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Luminance Curve] +Brightness=0 +Contrast=-25 +Chromaticity=0 +BWtoning=true +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; +LcCurve=0; + +[Sharpening] +Enabled=false +Method=usm +Radius=0.5 +Amount=125 +Threshold=20;80;2000;1200; +OnlyEdges=false +EdgedetectionRadius=1.9 +EdgeTolerance=1800 +HalocontrolEnabled=false +HalocontrolAmount=85 +DeconvRadius=0.75 +DeconvAmount=75 +DeconvDamping=20 +DeconvIterations=30 + +[Vibrance] +Enabled=false +Pastels=50 +Saturated=50 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=true +PastSatTog=true +SkinTonesCurve=0; + +[SharpenEdge] +Enabled=false +Passes=2 +Strength=50 +ThreeChannels=false + +[SharpenMicro] +Enabled=false +Matrix=false +Strength=20 +Uniformity=50 + +[White Balance] +Setting=Camera +Temperature=5745 +Green=1.0 + +[Impulse Denoising] +Enabled=false +Threshold=50 + +[Defringing] +Enabled=false +Radius=2.0 +Threshold=25 + +[Directional Pyramid Denoising] +Enabled=false +Luma=0 +Ldetail=80 +Chroma=15 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.4 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=10 +HighlightTonalWidth=80 +Shadows=10 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=30 + +[Crop] +Enabled=false +X=0 +Y=0 +W=7360 +H=4912 +FixedRatio=false +Ratio=3:2 +Orientation=Landscape +Guide=None + +[Coarse Transformation] +Rotate=0 +HorizontalFlip=false +VerticalFlip=false + +[Common Properties for Transformations] +AutoFill=true + +[Rotation] +Degree=0 + +[Distortion] +Amount=0 + +[LensProfile] +LCPFile= +UseDistortion=true +UseVignette=true +UseCA=false + +[Perspective] +Horizontal=0 +Vertical=0 + +[CACorrection] +Red=0 +Blue=0 + +[Vignetting Correction] +Amount=0 +Radius=50 +Strength=1 +CenterX=0 +CenterY=0 + +[HLRecovery] +Enabled=false +Method=Blend + +[Resize] +Enabled=false +Scale=1 +AppliesTo=Cropped area +Method=Lanczos +DataSpecified=3 +Width=900 +Height=900 + +[Color Management] +InputProfile=(cameraICC) +BlendCMSMatrix=true +WorkingProfile=sRGB +OutputProfile=No ICM: sRGB output +Gammafree=default +Freegamma=false +GammaValue=2.22 +GammaSlope=4.5 + +[Directional Pyramid Equalizer] +Enabled=true +Mult0=3 +Mult1=1 +Mult2=1 +Mult3=1 +Mult4=0.2 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +rCurve=0; +gCurve=0; +bCurve=0; + +[RAW] +DarkFrame= +DarkFrameAuto=false +FlatFieldFile= +FlatFieldAutoSelect=false +FlatFieldBlurRadius=32 +FlatFieldBlurType=Area Flatfield +CA=false +CARed=0 +CABlue=0 +HotDeadPixels=false +HotDeadPixelThresh=40 +LineDenoise=0 +GreenEqThreshold=0 +CcSteps=0 +Method=amaze +DCBIterations=2 +DCBEnhance=false +ALLEnhance=false +PreExposure=1 +PrePreserv=0 +PreBlackzero=0 +PreBlackone=0 +PreBlacktwo=0 +PreBlackthree=0 +PreTwoGreen=true diff --git a/rtdata/profiles/BW-4.pp3 b/rtdata/profiles/BW-4.pp3 new file mode 100644 index 000000000..03b394eb3 --- /dev/null +++ b/rtdata/profiles/BW-4.pp3 @@ -0,0 +1,236 @@ + +[Version] +AppVersion=4.0.9 +Version=305 + +[General] +Rank=0 +ColorLabel=0 +InTrash=false + +[Exposure] +Auto=true +Clip=0.0000 +Compensation=0 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=0 +HighlightComprThreshold=33 +ShadowCompr=50 +CurveMode=Standard +Curve=0; +CurveMode2=Standard +Curve2=0; + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Luminance Curve] +Brightness=0 +Contrast=-35 +Chromaticity=0 +BWtoning=true +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; +LcCurve=0; + +[Sharpening] +Enabled=false +Method=usm +Radius=0.5 +Amount=125 +Threshold=20;80;2000;1200; +OnlyEdges=false +EdgedetectionRadius=1.9 +EdgeTolerance=1800 +HalocontrolEnabled=false +HalocontrolAmount=85 +DeconvRadius=0.75 +DeconvAmount=75 +DeconvDamping=20 +DeconvIterations=30 + +[Vibrance] +Enabled=false +Pastels=50 +Saturated=50 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=true +PastSatTog=true +SkinTonesCurve=0; + +[SharpenEdge] +Enabled=false +Passes=2 +Strength=50 +ThreeChannels=false + +[SharpenMicro] +Enabled=false +Matrix=false +Strength=20 +Uniformity=50 + +[White Balance] +Setting=Camera +Temperature=5745 +Green=1.0 + +[Impulse Denoising] +Enabled=false +Threshold=50 + +[Defringing] +Enabled=false +Radius=2.0 +Threshold=25 + + +[Directional Pyramid Denoising] +Enabled=false +Luma=0 +Ldetail=80 +Chroma=15 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.4 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=10 +HighlightTonalWidth=80 +Shadows=10 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=30 + +[Crop] +Enabled=false +X=0 +Y=0 +W=7360 +H=4912 +FixedRatio=false +Ratio=3:2 +Orientation=Landscape +Guide=None + +[Coarse Transformation] +Rotate=0 +HorizontalFlip=false +VerticalFlip=false + +[Common Properties for Transformations] +AutoFill=true + +[Rotation] +Degree=0 + +[Distortion] +Amount=0 + +[LensProfile] +LCPFile= +UseDistortion=true +UseVignette=true +UseCA=false + +[Perspective] +Horizontal=0 +Vertical=0 + +[CACorrection] +Red=0 +Blue=0 + +[Vignetting Correction] +Amount=0 +Radius=50 +Strength=1 +CenterX=0 +CenterY=0 + +[HLRecovery] +Enabled=false +Method=Blend + +[Resize] +Enabled=false +Scale=1 +AppliesTo=Cropped area +Method=Lanczos +DataSpecified=3 +Width=900 +Height=900 + +[Color Management] +InputProfile=(cameraICC) +BlendCMSMatrix=true +WorkingProfile=sRGB +OutputProfile=No ICM: sRGB output +Gammafree=default +Freegamma=false +GammaValue=2.22 +GammaSlope=4.5 + +[Directional Pyramid Equalizer] +Enabled=true +Mult0=3 +Mult1=1 +Mult2=1 +Mult3=1 +Mult4=0.2 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +rCurve=0; +gCurve=0; +bCurve=0; + +[RAW] +DarkFrame= +DarkFrameAuto=false +FlatFieldFile= +FlatFieldAutoSelect=false +FlatFieldBlurRadius=32 +FlatFieldBlurType=Area Flatfield +CA=false +CARed=0 +CABlue=0 +HotDeadPixels=false +HotDeadPixelThresh=40 +LineDenoise=0 +GreenEqThreshold=0 +CcSteps=0 +Method=amaze +DCBIterations=2 +DCBEnhance=false +ALLEnhance=false +PreExposure=1 +PrePreserv=0 +PreBlackzero=0 +PreBlackone=0 +PreBlacktwo=0 +PreBlackthree=0 +PreTwoGreen=true diff --git a/rtdata/profiles/Default-ISO-High.pp3 b/rtdata/profiles/Default-ISO-High.pp3 new file mode 100644 index 000000000..4d839002c --- /dev/null +++ b/rtdata/profiles/Default-ISO-High.pp3 @@ -0,0 +1,235 @@ + +[Version] +AppVersion=4.0.9 +Version=305 + +[General] +Rank=0 +ColorLabel=0 +InTrash=false + +[Exposure] +Auto=true +Clip=0.0000 +Compensation=0 +Brightness=0 +Contrast=20 +Saturation=5 +Black=0 +HighlightCompr=0 +HighlightComprThreshold=33 +ShadowCompr=50 +CurveMode=Standard +Curve=0; +CurveMode2=Standard +Curve2=0; + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=5 +BWtoning=false +AvoidColorShift=true +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; + +[Sharpening] +Enabled=false +Method=usm +Radius=0.5 +Amount=125 +Threshold=20;80;2000;1200; +OnlyEdges=false +EdgedetectionRadius=1.9 +EdgeTolerance=1800 +HalocontrolEnabled=false +HalocontrolAmount=85 +DeconvRadius=0.75 +DeconvAmount=75 +DeconvDamping=20 +DeconvIterations=30 + +[Vibrance] +Enabled=false +Pastels=50 +Saturated=50 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=true +PastSatTog=true +SkinTonesCurve=0; + +[SharpenEdge] +Enabled=false +Passes=2 +Strength=50 +ThreeChannels=false + +[SharpenMicro] +Enabled=false +Matrix=false +Strength=20 +Uniformity=50 + +[White Balance] +Setting=Camera +Temperature=5745 +Green=1.0 + +[Impulse Denoising] +Enabled=false +Threshold=80 + +[Defringing] +Enabled=false +Radius=2.0 +Threshold=25 + +[Directional Pyramid Denoising] +Enabled=true +Luma=50 +Ldetail=80 +Chroma=50 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.4 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=10 +HighlightTonalWidth=80 +Shadows=10 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=30 + +[Crop] +Enabled=false +X=0 +Y=0 +W=7360 +H=4912 +FixedRatio=false +Ratio=3:2 +Orientation=Landscape +Guide=None + +[Coarse Transformation] +Rotate=0 +HorizontalFlip=false +VerticalFlip=false + +[Common Properties for Transformations] +AutoFill=true + +[Rotation] +Degree=0 + +[Distortion] +Amount=0 + +[LensProfile] +LCPFile= +UseDistortion=true +UseVignette=true +UseCA=false + +[Perspective] +Horizontal=0 +Vertical=0 + +[CACorrection] +Red=0 +Blue=0 + +[Vignetting Correction] +Amount=0 +Radius=50 +Strength=1 +CenterX=0 +CenterY=0 + +[HLRecovery] +Enabled=false +Method=Blend + +[Resize] +Enabled=false +Scale=1 +AppliesTo=Cropped area +Method=Lanczos +DataSpecified=3 +Width=900 +Height=900 + +[Color Management] +InputProfile=(cameraICC) +BlendCMSMatrix=true +WorkingProfile=sRGB +OutputProfile=No ICM: sRGB output +Gammafree=default +Freegamma=false +GammaValue=2.22 +GammaSlope=4.5 + +[Directional Pyramid Equalizer] +Enabled=true +Mult0=1 +Mult1=2 +Mult2=1 +Mult3=1 +Mult4=0.5 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +rCurve=0; +gCurve=0; +bCurve=0; + +[RAW] +DarkFrame= +DarkFrameAuto=false +FlatFieldFile= +FlatFieldAutoSelect=false +FlatFieldBlurRadius=32 +FlatFieldBlurType=Area Flatfield +CA=false +CARed=0 +CABlue=0 +HotDeadPixels=false +HotDeadPixelThresh=40 +LineDenoise=0 +GreenEqThreshold=0 +CcSteps=0 +Method=amaze +DCBIterations=2 +DCBEnhance=false +ALLEnhance=false +PreExposure=1 +PrePreserv=0 +PreBlackzero=0 +PreBlackone=0 +PreBlacktwo=0 +PreBlackthree=0 +PreTwoGreen=true diff --git a/rtdata/profiles/Default-ISO-Medium.pp3 b/rtdata/profiles/Default-ISO-Medium.pp3 new file mode 100644 index 000000000..56d4d9a57 --- /dev/null +++ b/rtdata/profiles/Default-ISO-Medium.pp3 @@ -0,0 +1,235 @@ + +[Version] +AppVersion=4.0.9 +Version=305 + +[General] +Rank=0 +ColorLabel=0 +InTrash=false + +[Exposure] +Auto=true +Clip=0.0000 +Compensation=0 +Brightness=0 +Contrast=20 +Saturation=5 +Black=0 +HighlightCompr=0 +HighlightComprThreshold=33 +ShadowCompr=50 +CurveMode=Standard +Curve=0; +CurveMode2=Standard +Curve2=0; + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=5 +BWtoning=false +AvoidColorShift=true +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; + +[Sharpening] +Enabled=false +Method=usm +Radius=0.5 +Amount=125 +Threshold=20;80;2000;1200; +OnlyEdges=false +EdgedetectionRadius=1.9 +EdgeTolerance=1800 +HalocontrolEnabled=false +HalocontrolAmount=85 +DeconvRadius=0.75 +DeconvAmount=75 +DeconvDamping=20 +DeconvIterations=30 + +[Vibrance] +Enabled=false +Pastels=50 +Saturated=50 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=true +PastSatTog=true +SkinTonesCurve=0; + +[SharpenEdge] +Enabled=false +Passes=2 +Strength=50 +ThreeChannels=false + +[SharpenMicro] +Enabled=false +Matrix=false +Strength=20 +Uniformity=50 + +[White Balance] +Setting=Camera +Temperature=5745 +Green=1.0 + +[Impulse Denoising] +Enabled=false +Threshold=50 + +[Defringing] +Enabled=false +Radius=2.0 +Threshold=25 + +[Directional Pyramid Denoising] +Enabled=true +Luma=20 +Ldetail=80 +Chroma=30 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.4 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=10 +HighlightTonalWidth=80 +Shadows=10 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=30 + +[Crop] +Enabled=false +X=0 +Y=0 +W=7360 +H=4912 +FixedRatio=false +Ratio=3:2 +Orientation=Landscape +Guide=None + +[Coarse Transformation] +Rotate=0 +HorizontalFlip=false +VerticalFlip=false + +[Common Properties for Transformations] +AutoFill=true + +[Rotation] +Degree=0 + +[Distortion] +Amount=0 + +[LensProfile] +LCPFile= +UseDistortion=true +UseVignette=true +UseCA=false + +[Perspective] +Horizontal=0 +Vertical=0 + +[CACorrection] +Red=0 +Blue=0 + +[Vignetting Correction] +Amount=0 +Radius=50 +Strength=1 +CenterX=0 +CenterY=0 + +[HLRecovery] +Enabled=false +Method=Blend + +[Resize] +Enabled=false +Scale=1 +AppliesTo=Cropped area +Method=Lanczos +DataSpecified=3 +Width=900 +Height=900 + +[Color Management] +InputProfile=(cameraICC) +BlendCMSMatrix=true +WorkingProfile=sRGB +OutputProfile=No ICM: sRGB output +Gammafree=default +Freegamma=false +GammaValue=2.22 +GammaSlope=4.5 + +[Directional Pyramid Equalizer] +Enabled=true +Mult0=1 +Mult1=2 +Mult2=1 +Mult3=1 +Mult4=0.5 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +rCurve=0; +gCurve=0; +bCurve=0; + +[RAW] +DarkFrame= +DarkFrameAuto=false +FlatFieldFile= +FlatFieldAutoSelect=false +FlatFieldBlurRadius=32 +FlatFieldBlurType=Area Flatfield +CA=false +CARed=0 +CABlue=0 +HotDeadPixels=false +HotDeadPixelThresh=40 +LineDenoise=0 +GreenEqThreshold=0 +CcSteps=0 +Method=amaze +DCBIterations=2 +DCBEnhance=false +ALLEnhance=false +PreExposure=1 +PrePreserv=0 +PreBlackzero=0 +PreBlackone=0 +PreBlacktwo=0 +PreBlackthree=0 +PreTwoGreen=true diff --git a/rtdata/profiles/Default.pp3 b/rtdata/profiles/Default.pp3 new file mode 100644 index 000000000..84a29cb06 --- /dev/null +++ b/rtdata/profiles/Default.pp3 @@ -0,0 +1,235 @@ + +[Version] +AppVersion=4.0.9 +Version=305 + +[General] +Rank=0 +ColorLabel=0 +InTrash=false + +[Exposure] +Auto=true +Clip=0.0000 +Compensation=0 +Brightness=0 +Contrast=0 +Saturation=5 +Black=0 +HighlightCompr=0 +HighlightComprThreshold=33 +ShadowCompr=50 +CurveMode=Standard +Curve=0; +CurveMode2=Standard +Curve2=0; + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=5 +BWtoning=false +AvoidColorShift=true +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; + +[Sharpening] +Enabled=false +Method=usm +Radius=0.5 +Amount=125 +Threshold=20;80;2000;1200; +OnlyEdges=false +EdgedetectionRadius=1.9 +EdgeTolerance=1800 +HalocontrolEnabled=false +HalocontrolAmount=85 +DeconvRadius=0.75 +DeconvAmount=75 +DeconvDamping=20 +DeconvIterations=30 + +[Vibrance] +Enabled=false +Pastels=50 +Saturated=50 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=true +PastSatTog=true +SkinTonesCurve=0; + +[SharpenEdge] +Enabled=false +Passes=2 +Strength=50 +ThreeChannels=false + +[SharpenMicro] +Enabled=false +Matrix=false +Strength=20 +Uniformity=50 + +[White Balance] +Setting=Camera +Temperature=5745 +Green=1.0 + +[Impulse Denoising] +Enabled=false +Threshold=50 + +[Defringing] +Enabled=false +Radius=2.0 +Threshold=25 + +[Directional Pyramid Denoising] +Enabled=false +Luma=0 +Ldetail=80 +Chroma=15 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.4 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=10 +HighlightTonalWidth=80 +Shadows=10 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=30 + +[Crop] +Enabled=false +X=0 +Y=0 +W=7360 +H=4912 +FixedRatio=false +Ratio=3:2 +Orientation=Landscape +Guide=None + +[Coarse Transformation] +Rotate=0 +HorizontalFlip=false +VerticalFlip=false + +[Common Properties for Transformations] +AutoFill=true + +[Rotation] +Degree=0 + +[Distortion] +Amount=0 + +[LensProfile] +LCPFile= +UseDistortion=true +UseVignette=true +UseCA=false + +[Perspective] +Horizontal=0 +Vertical=0 + +[CACorrection] +Red=0 +Blue=0 + +[Vignetting Correction] +Amount=0 +Radius=50 +Strength=1 +CenterX=0 +CenterY=0 + +[HLRecovery] +Enabled=false +Method=Blend + +[Resize] +Enabled=false +Scale=1 +AppliesTo=Cropped area +Method=Lanczos +DataSpecified=3 +Width=900 +Height=900 + +[Color Management] +InputProfile=(cameraICC) +BlendCMSMatrix=true +WorkingProfile=sRGB +OutputProfile=No ICM: sRGB output +Gammafree=default +Freegamma=false +GammaValue=2.22 +GammaSlope=4.5 + +[Directional Pyramid Equalizer] +Enabled=true +Mult0=3 +Mult1=1 +Mult2=1 +Mult3=1 +Mult4=0.2 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +rCurve=0; +gCurve=0; +bCurve=0; + +[RAW] +DarkFrame= +DarkFrameAuto=false +FlatFieldFile= +FlatFieldAutoSelect=false +FlatFieldBlurRadius=32 +FlatFieldBlurType=Area Flatfield +CA=false +CARed=0 +CABlue=0 +HotDeadPixels=false +HotDeadPixelThresh=40 +LineDenoise=0 +GreenEqThreshold=0 +CcSteps=0 +Method=amaze +DCBIterations=2 +DCBEnhance=false +ALLEnhance=false +PreExposure=1 +PrePreserv=0 +PreBlackzero=0 +PreBlackone=0 +PreBlacktwo=0 +PreBlackthree=0 +PreTwoGreen=true diff --git a/rtdata/profiles/Highkey-1.pp3 b/rtdata/profiles/Highkey-1.pp3 new file mode 100644 index 000000000..d90907f28 --- /dev/null +++ b/rtdata/profiles/Highkey-1.pp3 @@ -0,0 +1,235 @@ + +[Version] +AppVersion=4.0.9 +Version=305 + +[General] +Rank=0 +ColorLabel=0 +InTrash=false + +[Exposure] +Auto=true +Clip=0.0000 +Compensation=0 +Brightness=0 +Contrast=0 +Saturation=-10 +Black=0 +HighlightCompr=0 +HighlightComprThreshold=33 +ShadowCompr=50 +CurveMode=Standard +Curve=2;0.105;0.25;0.75;15;60;30;-70; +CurveMode2=Standard +Curve2=0; + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Luminance Curve] +Brightness=0 +Contrast=5 +Chromaticity=-10 +BWtoning=false +AvoidColorShift=true +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; + +[Sharpening] +Enabled=false +Method=usm +Radius=0.5 +Amount=125 +Threshold=20;80;2000;1200; +OnlyEdges=false +EdgedetectionRadius=1.9 +EdgeTolerance=1800 +HalocontrolEnabled=false +HalocontrolAmount=85 +DeconvRadius=0.75 +DeconvAmount=75 +DeconvDamping=20 +DeconvIterations=30 + +[Vibrance] +Enabled=false +Pastels=50 +Saturated=50 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=true +PastSatTog=true +SkinTonesCurve=0; + +[SharpenEdge] +Enabled=false +Passes=2 +Strength=50 +ThreeChannels=false + +[SharpenMicro] +Enabled=false +Matrix=false +Strength=20 +Uniformity=50 + +[White Balance] +Setting=Camera +Temperature=5745 +Green=1.0 + +[Impulse Denoising] +Enabled=false +Threshold=50 + +[Defringing] +Enabled=false +Radius=2.0 +Threshold=25 + +[Directional Pyramid Denoising] +Enabled=false +Luma=0 +Ldetail=80 +Chroma=15 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.4 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=10 +HighlightTonalWidth=80 +Shadows=10 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=30 + +[Crop] +Enabled=false +X=0 +Y=0 +W=7360 +H=4912 +FixedRatio=false +Ratio=3:2 +Orientation=Landscape +Guide=None + +[Coarse Transformation] +Rotate=0 +HorizontalFlip=false +VerticalFlip=false + +[Common Properties for Transformations] +AutoFill=true + +[Rotation] +Degree=0 + +[Distortion] +Amount=0 + +[LensProfile] +LCPFile= +UseDistortion=true +UseVignette=true +UseCA=false + +[Perspective] +Horizontal=0 +Vertical=0 + +[CACorrection] +Red=0 +Blue=0 + +[Vignetting Correction] +Amount=0 +Radius=50 +Strength=1 +CenterX=0 +CenterY=0 + +[HLRecovery] +Enabled=false +Method=Blend + +[Resize] +Enabled=false +Scale=1 +AppliesTo=Cropped area +Method=Lanczos +DataSpecified=3 +Width=900 +Height=900 + +[Color Management] +InputProfile=(cameraICC) +BlendCMSMatrix=true +WorkingProfile=sRGB +OutputProfile=No ICM: sRGB output +Gammafree=default +Freegamma=false +GammaValue=2.22 +GammaSlope=4.5 + +[Directional Pyramid Equalizer] +Enabled=true +Mult0=3 +Mult1=1 +Mult2=1 +Mult3=1 +Mult4=0.2 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +rCurve=0; +gCurve=0; +bCurve=0; + +[RAW] +DarkFrame= +DarkFrameAuto=false +FlatFieldFile= +FlatFieldAutoSelect=false +FlatFieldBlurRadius=32 +FlatFieldBlurType=Area Flatfield +CA=false +CARed=0 +CABlue=0 +HotDeadPixels=false +HotDeadPixelThresh=40 +LineDenoise=0 +GreenEqThreshold=0 +CcSteps=0 +Method=amaze +DCBIterations=2 +DCBEnhance=false +ALLEnhance=false +PreExposure=1 +PrePreserv=0 +PreBlackzero=0 +PreBlackone=0 +PreBlacktwo=0 +PreBlackthree=0 +PreTwoGreen=true diff --git a/rtdata/profiles/Natural-1.pp3 b/rtdata/profiles/Natural-1.pp3 new file mode 100644 index 000000000..27a1b37db --- /dev/null +++ b/rtdata/profiles/Natural-1.pp3 @@ -0,0 +1,235 @@ + +[Version] +AppVersion=4.0.9 +Version=305 + +[General] +Rank=0 +ColorLabel=0 +InTrash=false + +[Exposure] +Auto=true +Clip=0.0000 +Compensation=0 +Brightness=0 +Contrast=20 +Saturation=0 +Black=0 +HighlightCompr=0 +HighlightComprThreshold=33 +ShadowCompr=50 +CurveMode=Standard +Curve=1;0;0;0.04;0.03;0.17684498029510265;0.21732319394192093;0.70232558139534862;0.74883720930232545;1;1; +CurveMode2=Standard +Curve2=0; + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=0 +BWtoning=false +AvoidColorShift=true +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; + +[Sharpening] +Enabled=false +Method=usm +Radius=0.5 +Amount=125 +Threshold=20;80;2000;1200; +OnlyEdges=false +EdgedetectionRadius=1.9 +EdgeTolerance=1800 +HalocontrolEnabled=false +HalocontrolAmount=85 +DeconvRadius=0.75 +DeconvAmount=75 +DeconvDamping=20 +DeconvIterations=30 + +[Vibrance] +Enabled=false +Pastels=50 +Saturated=50 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=true +PastSatTog=true +SkinTonesCurve=0; + +[SharpenEdge] +Enabled=false +Passes=2 +Strength=50 +ThreeChannels=false + +[SharpenMicro] +Enabled=false +Matrix=false +Strength=20 +Uniformity=50 + +[White Balance] +Setting=Camera +Temperature=5745 +Green=1.0 + +[Impulse Denoising] +Enabled=false +Threshold=50 + +[Defringing] +Enabled=false +Radius=2.0 +Threshold=25 + +[Directional Pyramid Denoising] +Enabled=false +Luma=0 +Ldetail=80 +Chroma=15 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.4 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=10 +HighlightTonalWidth=80 +Shadows=10 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=30 + +[Crop] +Enabled=false +X=0 +Y=0 +W=7360 +H=4912 +FixedRatio=false +Ratio=3:2 +Orientation=Landscape +Guide=None + +[Coarse Transformation] +Rotate=0 +HorizontalFlip=false +VerticalFlip=false + +[Common Properties for Transformations] +AutoFill=true + +[Rotation] +Degree=0 + +[Distortion] +Amount=0 + +[LensProfile] +LCPFile= +UseDistortion=true +UseVignette=true +UseCA=false + +[Perspective] +Horizontal=0 +Vertical=0 + +[CACorrection] +Red=0 +Blue=0 + +[Vignetting Correction] +Amount=0 +Radius=50 +Strength=1 +CenterX=0 +CenterY=0 + +[HLRecovery] +Enabled=false +Method=Blend + +[Resize] +Enabled=false +Scale=1 +AppliesTo=Cropped area +Method=Lanczos +DataSpecified=3 +Width=900 +Height=900 + +[Color Management] +InputProfile=(cameraICC) +BlendCMSMatrix=true +WorkingProfile=sRGB +OutputProfile=No ICM: sRGB output +Gammafree=default +Freegamma=false +GammaValue=2.22 +GammaSlope=4.5 + +[Directional Pyramid Equalizer] +Enabled=true +Mult0=3 +Mult1=1 +Mult2=1 +Mult3=1 +Mult4=0.2 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +rCurve=0; +gCurve=0; +bCurve=0; + +[RAW] +DarkFrame= +DarkFrameAuto=false +FlatFieldFile= +FlatFieldAutoSelect=false +FlatFieldBlurRadius=32 +FlatFieldBlurType=Area Flatfield +CA=false +CARed=0 +CABlue=0 +HotDeadPixels=false +HotDeadPixelThresh=40 +LineDenoise=0 +GreenEqThreshold=0 +CcSteps=0 +Method=amaze +DCBIterations=2 +DCBEnhance=false +ALLEnhance=false +PreExposure=1 +PrePreserv=0 +PreBlackzero=0 +PreBlackone=0 +PreBlacktwo=0 +PreBlackthree=0 +PreTwoGreen=true diff --git a/rtdata/profiles/Natural-2.pp3 b/rtdata/profiles/Natural-2.pp3 new file mode 100644 index 000000000..6e14e5f9b --- /dev/null +++ b/rtdata/profiles/Natural-2.pp3 @@ -0,0 +1,235 @@ + +[Version] +AppVersion=4.0.9 +Version=305 + +[General] +Rank=0 +ColorLabel=0 +InTrash=false + +[Exposure] +Auto=true +Clip=0.0000 +Compensation=0 +Brightness=0 +Contrast=20 +Saturation=5 +Black=0 +HighlightCompr=0 +HighlightComprThreshold=33 +ShadowCompr=50 +CurveMode=Standard +Curve=1;0;0;0.45754265471370759;0.57906737998843294;1;1; +CurveMode2=Standard +Curve2=0; + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=5 +BWtoning=false +AvoidColorShift=true +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=3;0;0;0.84892086330935235;0.69064748201438808;1;1; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; + +[Sharpening] +Enabled=false +Method=usm +Radius=0.5 +Amount=125 +Threshold=20;80;2000;1200; +OnlyEdges=false +EdgedetectionRadius=1.9 +EdgeTolerance=1800 +HalocontrolEnabled=false +HalocontrolAmount=85 +DeconvRadius=0.75 +DeconvAmount=75 +DeconvDamping=20 +DeconvIterations=30 + +[Vibrance] +Enabled=false +Pastels=50 +Saturated=50 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=true +PastSatTog=true +SkinTonesCurve=0; + +[SharpenEdge] +Enabled=false +Passes=2 +Strength=50 +ThreeChannels=false + +[SharpenMicro] +Enabled=false +Matrix=false +Strength=20 +Uniformity=50 + +[White Balance] +Setting=Camera +Temperature=5745 +Green=1.0 + +[Impulse Denoising] +Enabled=false +Threshold=50 + +[Defringing] +Enabled=false +Radius=2.0 +Threshold=25 + +[Directional Pyramid Denoising] +Enabled=false +Luma=0 +Ldetail=80 +Chroma=15 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.4 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=10 +HighlightTonalWidth=80 +Shadows=10 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=30 + +[Crop] +Enabled=false +X=0 +Y=0 +W=7360 +H=4912 +FixedRatio=false +Ratio=3:2 +Orientation=Landscape +Guide=None + +[Coarse Transformation] +Rotate=0 +HorizontalFlip=false +VerticalFlip=false + +[Common Properties for Transformations] +AutoFill=true + +[Rotation] +Degree=0 + +[Distortion] +Amount=0 + +[LensProfile] +LCPFile= +UseDistortion=true +UseVignette=true +UseCA=false + +[Perspective] +Horizontal=0 +Vertical=0 + +[CACorrection] +Red=0 +Blue=0 + +[Vignetting Correction] +Amount=0 +Radius=50 +Strength=1 +CenterX=0 +CenterY=0 + +[HLRecovery] +Enabled=false +Method=Blend + +[Resize] +Enabled=false +Scale=1 +AppliesTo=Cropped area +Method=Lanczos +DataSpecified=3 +Width=900 +Height=900 + +[Color Management] +InputProfile=(cameraICC) +BlendCMSMatrix=true +WorkingProfile=sRGB +OutputProfile=No ICM: sRGB output +Gammafree=default +Freegamma=false +GammaValue=2.22 +GammaSlope=4.5 + +[Directional Pyramid Equalizer] +Enabled=true +Mult0=3 +Mult1=1 +Mult2=1 +Mult3=1 +Mult4=0.2 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +rCurve=0; +gCurve=0; +bCurve=0; + +[RAW] +DarkFrame= +DarkFrameAuto=false +FlatFieldFile= +FlatFieldAutoSelect=false +FlatFieldBlurRadius=32 +FlatFieldBlurType=Area Flatfield +CA=false +CARed=0 +CABlue=0 +HotDeadPixels=false +HotDeadPixelThresh=40 +LineDenoise=0 +GreenEqThreshold=0 +CcSteps=0 +Method=amaze +DCBIterations=2 +DCBEnhance=false +ALLEnhance=false +PreExposure=1 +PrePreserv=0 +PreBlackzero=0 +PreBlackone=0 +PreBlacktwo=0 +PreBlackthree=0 +PreTwoGreen=true diff --git a/rtdata/profiles/Neutral.pp3 b/rtdata/profiles/Neutral.pp3 new file mode 100644 index 000000000..bf41369b5 --- /dev/null +++ b/rtdata/profiles/Neutral.pp3 @@ -0,0 +1,235 @@ + +[Version] +AppVersion=4.0.9 +Version=305 + +[General] +Rank=0 +ColorLabel=0 +InTrash=false + +[Exposure] +Auto=false +Clip=0 +Compensation=0 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=0 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=Standard +Curve=0; +CurveMode2=Standard +Curve2=0; + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=0 +BWtoning=false +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; + +[Sharpening] +Enabled=false +Method=usm +Radius=0.5 +Amount=125 +Threshold=20;80;2000;1200; +OnlyEdges=false +EdgedetectionRadius=1.9 +EdgeTolerance=1800 +HalocontrolEnabled=false +HalocontrolAmount=85 +DeconvRadius=0.75 +DeconvAmount=75 +DeconvDamping=20 +DeconvIterations=30 + +[Vibrance] +Enabled=false +Pastels=50 +Saturated=50 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=true +PastSatTog=true +SkinTonesCurve=0; + +[SharpenEdge] +Enabled=false +Passes=2 +Strength=50 +ThreeChannels=false + +[SharpenMicro] +Enabled=false +Matrix=false +Strength=20 +Uniformity=50 + +[White Balance] +Setting=Camera +Temperature=5745 +Green=1.0 + +[Impulse Denoising] +Enabled=false +Threshold=50 + +[Defringing] +Enabled=false +Radius=2.0 +Threshold=25 + +[Directional Pyramid Denoising] +Enabled=false +Luma=0 +Ldetail=80 +Chroma=15 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.4 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=10 +HighlightTonalWidth=80 +Shadows=10 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=30 + +[Crop] +Enabled=false +X=0 +Y=0 +W=7360 +H=4912 +FixedRatio=false +Ratio=3:2 +Orientation=Landscape +Guide=None + +[Coarse Transformation] +Rotate=0 +HorizontalFlip=false +VerticalFlip=false + +[Common Properties for Transformations] +AutoFill=true + +[Rotation] +Degree=0 + +[Distortion] +Amount=0 + +[LensProfile] +LCPFile= +UseDistortion=true +UseVignette=true +UseCA=false + +[Perspective] +Horizontal=0 +Vertical=0 + +[CACorrection] +Red=0 +Blue=0 + +[Vignetting Correction] +Amount=0 +Radius=50 +Strength=1 +CenterX=0 +CenterY=0 + +[HLRecovery] +Enabled=false +Method=Blend + +[Resize] +Enabled=false +Scale=1 +AppliesTo=Cropped area +Method=Lanczos +DataSpecified=3 +Width=900 +Height=900 + +[Color Management] +InputProfile=(cameraICC) +BlendCMSMatrix=true +WorkingProfile=sRGB +OutputProfile=No ICM: sRGB output +Gammafree=default +Freegamma=false +GammaValue=2.22 +GammaSlope=4.5 + +[Directional Pyramid Equalizer] +Enabled=false +Mult0=1 +Mult1=1 +Mult2=1 +Mult3=1 +Mult4=0.2 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +rCurve=0; +gCurve=0; +bCurve=0; + +[RAW] +DarkFrame= +DarkFrameAuto=false +FlatFieldFile= +FlatFieldAutoSelect=false +FlatFieldBlurRadius=32 +FlatFieldBlurType=Area Flatfield +CA=false +CARed=0 +CABlue=0 +HotDeadPixels=false +HotDeadPixelThresh=40 +LineDenoise=0 +GreenEqThreshold=0 +CcSteps=0 +Method=amaze +DCBIterations=2 +DCBEnhance=false +ALLEnhance=false +PreExposure=1 +PrePreserv=0 +PreBlackzero=0 +PreBlackone=0 +PreBlacktwo=0 +PreBlackthree=0 +PreTwoGreen=true diff --git a/rtdata/profiles/Punchy-1.pp3 b/rtdata/profiles/Punchy-1.pp3 new file mode 100644 index 000000000..2c52362ba --- /dev/null +++ b/rtdata/profiles/Punchy-1.pp3 @@ -0,0 +1,235 @@ + +[Version] +AppVersion=4.0.9 +Version=305 + +[General] +Rank=0 +ColorLabel=0 +InTrash=false + +[Exposure] +Auto=true +Clip=0.0000 +Compensation=0 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=0 +HighlightComprThreshold=33 +ShadowCompr=50 +CurveMode=Standard +Curve=0; +CurveMode2=Standard +Curve2=0; + +[Channel Mixer] +Red=120;-10;-10; +Green=-10;120;-10; +Blue=-10;-10;120; + +[Luminance Curve] +Brightness=0 +Contrast=10 +Chromaticity=5 +BWtoning=false +AvoidColorShift=true +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; + +[Sharpening] +Enabled=false +Method=usm +Radius=0.5 +Amount=125 +Threshold=20;80;2000;1200; +OnlyEdges=false +EdgedetectionRadius=1.9 +EdgeTolerance=1800 +HalocontrolEnabled=false +HalocontrolAmount=85 +DeconvRadius=0.75 +DeconvAmount=75 +DeconvDamping=20 +DeconvIterations=30 + +[Vibrance] +Enabled=false +Pastels=50 +Saturated=50 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=true +PastSatTog=true +SkinTonesCurve=0; + +[SharpenEdge] +Enabled=false +Passes=2 +Strength=50 +ThreeChannels=false + +[SharpenMicro] +Enabled=false +Matrix=false +Strength=20 +Uniformity=50 + +[White Balance] +Setting=Camera +Temperature=5745 +Green=1.0 + +[Impulse Denoising] +Enabled=false +Threshold=50 + +[Defringing] +Enabled=false +Radius=2.0 +Threshold=25 + +[Directional Pyramid Denoising] +Enabled=false +Luma=0 +Ldetail=80 +Chroma=15 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.4 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=10 +HighlightTonalWidth=80 +Shadows=10 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=30 + +[Crop] +Enabled=false +X=0 +Y=0 +W=7360 +H=4912 +FixedRatio=false +Ratio=3:2 +Orientation=Landscape +Guide=None + +[Coarse Transformation] +Rotate=0 +HorizontalFlip=false +VerticalFlip=false + +[Common Properties for Transformations] +AutoFill=true + +[Rotation] +Degree=0 + +[Distortion] +Amount=0 + +[LensProfile] +LCPFile= +UseDistortion=true +UseVignette=true +UseCA=false + +[Perspective] +Horizontal=0 +Vertical=0 + +[CACorrection] +Red=0 +Blue=0 + +[Vignetting Correction] +Amount=0 +Radius=50 +Strength=1 +CenterX=0 +CenterY=0 + +[HLRecovery] +Enabled=false +Method=Blend + +[Resize] +Enabled=false +Scale=1 +AppliesTo=Cropped area +Method=Lanczos +DataSpecified=3 +Width=900 +Height=900 + +[Color Management] +InputProfile=(cameraICC) +BlendCMSMatrix=true +WorkingProfile=sRGB +OutputProfile=No ICM: sRGB output +Gammafree=default +Freegamma=false +GammaValue=2.22 +GammaSlope=4.5 + +[Directional Pyramid Equalizer] +Enabled=true +Mult0=3 +Mult1=1.8 +Mult2=1.3 +Mult3=1 +Mult4=0.2 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +rCurve=0; +gCurve=0; +bCurve=0; + +[RAW] +DarkFrame= +DarkFrameAuto=false +FlatFieldFile= +FlatFieldAutoSelect=false +FlatFieldBlurRadius=32 +FlatFieldBlurType=Area Flatfield +CA=false +CARed=0 +CABlue=0 +HotDeadPixels=false +HotDeadPixelThresh=40 +LineDenoise=0 +GreenEqThreshold=0 +CcSteps=0 +Method=amaze +DCBIterations=2 +DCBEnhance=false +ALLEnhance=false +PreExposure=1 +PrePreserv=0 +PreBlackzero=0 +PreBlackone=0 +PreBlacktwo=0 +PreBlackthree=0 +PreTwoGreen=true diff --git a/rtdata/profiles/Punchy-2.pp3 b/rtdata/profiles/Punchy-2.pp3 new file mode 100644 index 000000000..ea7a18b9e --- /dev/null +++ b/rtdata/profiles/Punchy-2.pp3 @@ -0,0 +1,235 @@ + +[Version] +AppVersion=4.0.9 +Version=305 + +[General] +Rank=0 +ColorLabel=0 +InTrash=false + +[Exposure] +Auto=true +Clip=0.0000 +Compensation=0 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=0 +HighlightComprThreshold=33 +ShadowCompr=50 +CurveMode=Standard +Curve=0; +CurveMode2=Standard +Curve2=0; + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Luminance Curve] +Brightness=0 +Contrast=10 +Chromaticity=5 +BWtoning=false +AvoidColorShift=true +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; + +[Sharpening] +Enabled=false +Method=usm +Radius=0.5 +Amount=125 +Threshold=20;80;2000;1200; +OnlyEdges=false +EdgedetectionRadius=1.9 +EdgeTolerance=1800 +HalocontrolEnabled=false +HalocontrolAmount=85 +DeconvRadius=0.75 +DeconvAmount=75 +DeconvDamping=20 +DeconvIterations=30 + +[Vibrance] +Enabled=true +Pastels=50 +Saturated=50 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=true +PastSatTog=true +SkinTonesCurve=0; + +[SharpenEdge] +Enabled=false +Passes=2 +Strength=50 +ThreeChannels=false + +[SharpenMicro] +Enabled=false +Matrix=false +Strength=20 +Uniformity=50 + +[White Balance] +Setting=Camera +Temperature=5745 +Green=1.0 + +[Impulse Denoising] +Enabled=false +Threshold=50 + +[Defringing] +Enabled=false +Radius=2.0 +Threshold=25 + +[Directional Pyramid Denoising] +Enabled=false +Luma=0 +Ldetail=80 +Chroma=15 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.4 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=10 +HighlightTonalWidth=80 +Shadows=10 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=30 + +[Crop] +Enabled=false +X=0 +Y=0 +W=7360 +H=4912 +FixedRatio=false +Ratio=3:2 +Orientation=Landscape +Guide=None + +[Coarse Transformation] +Rotate=0 +HorizontalFlip=false +VerticalFlip=false + +[Common Properties for Transformations] +AutoFill=true + +[Rotation] +Degree=0 + +[Distortion] +Amount=0 + +[LensProfile] +LCPFile= +UseDistortion=true +UseVignette=true +UseCA=false + +[Perspective] +Horizontal=0 +Vertical=0 + +[CACorrection] +Red=0 +Blue=0 + +[Vignetting Correction] +Amount=0 +Radius=50 +Strength=1 +CenterX=0 +CenterY=0 + +[HLRecovery] +Enabled=false +Method=Blend + +[Resize] +Enabled=false +Scale=1 +AppliesTo=Cropped area +Method=Lanczos +DataSpecified=3 +Width=900 +Height=900 + +[Color Management] +InputProfile=(cameraICC) +BlendCMSMatrix=true +WorkingProfile=sRGB +OutputProfile=No ICM: sRGB output +Gammafree=default +Freegamma=false +GammaValue=2.22 +GammaSlope=4.5 + +[Directional Pyramid Equalizer] +Enabled=true +Mult0=3 +Mult1=1.8 +Mult2=1.3 +Mult3=1 +Mult4=0.2 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +rCurve=0; +gCurve=0; +bCurve=0; + +[RAW] +DarkFrame= +DarkFrameAuto=false +FlatFieldFile= +FlatFieldAutoSelect=false +FlatFieldBlurRadius=32 +FlatFieldBlurType=Area Flatfield +CA=false +CARed=0 +CABlue=0 +HotDeadPixels=false +HotDeadPixelThresh=40 +LineDenoise=0 +GreenEqThreshold=0 +CcSteps=0 +Method=amaze +DCBIterations=2 +DCBEnhance=false +ALLEnhance=false +PreExposure=1 +PrePreserv=0 +PreBlackzero=0 +PreBlackone=0 +PreBlacktwo=0 +PreBlackthree=0 +PreTwoGreen=true 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..f58deb2b3 --- /dev/null +++ b/rtdata/themes/09-Gray-Orange.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:#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-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..8852e496b --- /dev/null +++ b/rtdata/themes/17-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:#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-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..5c7cef224 --- /dev/null +++ b/rtdata/themes/21-Gray-Gray.gtkrc @@ -0,0 +1,499 @@ +# +# 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-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..c1e8c7959 --- /dev/null +++ b/rtdata/themes/25-Gray-Gray.gtkrc @@ -0,0 +1,485 @@ +# +# 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-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..3da71deda --- /dev/null +++ b/rtdata/themes/25-Gray-Purple.gtkrc @@ -0,0 +1,485 @@ +# +# 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-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..2956da69d --- /dev/null +++ b/rtdata/themes/25-Gray-Red.gtkrc @@ -0,0 +1,485 @@ +# +# 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-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..f3095612a --- /dev/null +++ b/rtdata/themes/37-Gray-Red-Textured.gtkrc @@ -0,0 +1,836 @@ +# +# 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_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_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" + } +} + +pixmap_path "themes/gray_textured" + +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 = "trough2.png" + border = { 6,6,6,6 } + stretch = TRUE + orientation = VERTICAL + } + image + { + function = BOX + detail = "trough" + file = "trough2-h.png" + border = { 6,6,6,6 } + stretch = TRUE + orientation = HORIZONTAL + } + image + { + function = SLIDER + state = NORMAL + file = "slider-h.png" + border = { 6,6,2,2 } + stretch = TRUE + orientation = HORIZONTAL + } + image + { + function = SLIDER + state = PRELIGHT + file = "slider-h-pre.png" + border = { 6,6,2,2 } + stretch = TRUE + orientation = HORIZONTAL + } + image + { + function = SLIDER + state = INSENSITIVE + file = "slider-h-ins.png" + border = { 6,6,2,2 } + stretch = TRUE + orientation = HORIZONTAL + } + image + { + function = SLIDER + state = NORMAL + file = "slider-v.png" + border = { 2, 2, 6, 6 } + stretch = TRUE + orientation = VERTICAL + } + image + { + function = SLIDER + state = PRELIGHT + file = "slider-v-pre.png" + border = { 2, 2, 6, 6 } + stretch = TRUE + orientation = VERTICAL + } + image + { + function = SLIDER + state = INSENSITIVE + file = "slider-v-ins.png" + border = { 2,2,6,6 } + stretch = TRUE + orientation = VERTICAL + } + image + { + function = STEPPER + state = NORMAL + file = "null.png" + border = { 1,1,4,4 } + stretch = TRUE + arrow_direction = UP + overlay_file = "arrow-up.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = PRELIGHT + file = "null.png" + border = { 1,1,4,4 } + stretch = TRUE + arrow_direction = UP + overlay_file = "arrow-up-pre.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = ACTIVE + file = "null.png" + border = { 1,1,4,4 } + stretch = TRUE + arrow_direction = UP + overlay_file = "arrow-up.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = INSENSITIVE + file = "null.png" + border = { 1,1,4,4 } + stretch = TRUE + arrow_direction = UP + overlay_file = "arrow-up-ins.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = NORMAL + file = "null.png" + border = { 1,1,4,4 } + stretch = TRUE + arrow_direction = DOWN + overlay_file = "arrow-down.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = PRELIGHT + file = "null.png" + border = { 1,1,4,4 } + stretch = TRUE + arrow_direction = DOWN + overlay_file = "arrow-down-pre.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = ACTIVE + file = "null.png" + border = { 1,1,4,4 } + stretch = TRUE + arrow_direction = DOWN + overlay_file = "arrow-down.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = INSENSITIVE + file = "null.png" + border = { 1,1,4,4 } + stretch = TRUE + arrow_direction = DOWN + overlay_file = "arrow-down-ins.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = NORMAL + file = "null.png" + border = { 4,4,1,1 } + stretch = TRUE + arrow_direction = RIGHT + overlay_file = "arrow-right.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = PRELIGHT + file = "null.png" + border = { 4,4,1,1 } + stretch = TRUE + arrow_direction = RIGHT + overlay_file = "arrow-right-pre.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = ACTIVE + file = "null.png" + border = { 4,4,1,1 } + stretch = TRUE + arrow_direction = RIGHT + overlay_file = "arrow-right.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = INSENSITIVE + file = "null.png" + border = { 4,4,1,1 } + stretch = TRUE + arrow_direction = RIGHT + overlay_file = "arrow-right-ins.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = NORMAL + file = "null.png" + border = { 4,4,1,1 } + stretch = TRUE + arrow_direction = LEFT + overlay_file = "arrow-left.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = PRELIGHT + file = "null.png" + border = { 4,4,1,1 } + stretch = TRUE + arrow_direction = LEFT + overlay_file = "arrow-left-pre.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = ACTIVE + file = "null.png" + border = { 4,4,1,1 } + stretch = TRUE + arrow_direction = LEFT + overlay_file = "arrow-left.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = INSENSITIVE + file = "null.png" + border = { 4,4,1,1 } + stretch = TRUE + arrow_direction = LEFT + overlay_file = "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 = "null.png" + # stretch = TRUE + # } + image + { + function = BOX + detail = "trough" + file = "pbtroughh.png" + border = { 6, 6, 6, 6 } + stretch = TRUE + orientation = HORIZONTAL + } + image + { + function = BOX + detail = "trough" + file = "pbtroughv.png" + border = { 6, 6, 6, 6 } + stretch = TRUE + orientation = VERTICAL + } + image + { + function = SLIDER + state = NORMAL + file = "rangeslider.png" + border = { 6, 6, 6, 6 } + stretch = TRUE + orientation = HORIZONTAL + } + image + { + function = SLIDER + state = PRELIGHT + file = "rangeslider-pre.png" + border = { 6, 6, 6, 6 } + stretch = TRUE + orientation = HORIZONTAL + } + image + { + function = SLIDER + state = ACTIVE + file = "rangeslider-pre.png" + border = { 6, 6, 6, 6 } + stretch = TRUE + orientation = HORIZONTAL + } + image + { + function = SLIDER + state = INSENSITIVE + file = "rangeslider-ins.png" + border = { 6, 6, 6, 6 } + stretch = TRUE + orientation = HORIZONTAL + } + image + { + function = SLIDER + state = NORMAL + file = "rangeslider.png" + border = { 6, 6, 6, 6 } + stretch = TRUE + orientation = VERTICAL + } + image + { + function = SLIDER + state = PRELIGHT + file = "rangeslider-pre.png" + border = { 6, 6, 6, 6 } + stretch = TRUE + orientation = VERTICAL + } + image + { + function = SLIDER + state = ACTIVE + file = "rangeslider-pre.png" + border = { 6, 6, 6, 6 } + stretch = TRUE + orientation = VERTICAL + } + image + { + function = SLIDER + state = INSENSITIVE + file = "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-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..aa5c37cb5 --- /dev/null +++ b/rtdata/themes/37-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:#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_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_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-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..d6c6d5a70 --- /dev/null +++ b/rtdata/themes/63-Gray-Cyan.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:#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-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..6d4faf9f1 --- /dev/null +++ b/rtdata/themes/92-Beige-DarkCyan.gtkrc @@ -0,0 +1,473 @@ +# +# 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-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..37383a20a --- /dev/null +++ b/rtdata/themes/Default.gtkrc @@ -0,0 +1,427 @@ +# +# 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-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..c1fc48af4 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..16b653ca4 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..607743404 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..3e9322bfd 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..9e8cbb8b3 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..ae6343824 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..0b3fd93bc 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..5f766898a 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..71a7856b5 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..e518dea63 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..6c669a3c7 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..7444ff414 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..9acefb9a4 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..b5122eab5 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..2c51eccfe 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..553988888 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..7b58b30ab 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..37cd0e3bf 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..6a547b608 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..03384cdd7 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..cc920d387 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..5cdb73d5b 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..6776a75ea 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..fdead8b3a 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..000477c64 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..d4523da69 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..3fc22aace 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..ecb505c7f 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..b92e4c236 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..309b487b4 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/rtengine/CA_correct_RT.cc b/rtengine/CA_correct_RT.cc new file mode 100644 index 000000000..f144bca57 --- /dev/null +++ b/rtengine/CA_correct_RT.cc @@ -0,0 +1,939 @@ +//////////////////////////////////////////////////////////////// +// +// 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, float* pfMatr, float* pfVect, float* 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 +// +//============================================================================== + + float fMaxElem; + float fAcc; + + int i, j, k, m; + + for(k=0; k<(nDim-1); k++) {// base row of matrix + // search of line with max element + fMaxElem = fabs( 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;} } + + // local variables + int width=W, height=H; + //temporary array to store simple interpolation of G + float (*Gtmp); + Gtmp = (float (*)) calloc ((height)*(width), sizeof *Gtmp); + + const int border=8; + const int border2=16; + //order of 2d polynomial fit (polyord), and numpar=polyord^2 + int polyord=4, numpar=16; + //number of blocks used in the fit + int numblox[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 vblsz, hblsz, vblock, hblock, vz1, hz1; + //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-5, eps2=1e-10; //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 + float polymat[3][2][256], shiftmat[3][2][16], fitparams[3][2][16]; + //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; + //data for evaluation of block CA shift variance + 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]; + //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]; // TS*TS*12 + //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(11*sizeof(float)*TS*TS); + //merror(buffer,"CA_correct()"); + memset(buffer,0,11*sizeof(float)*TS*TS); + + // rgb array + rgb = (float (*)[3]) buffer; + grbdiff = (float (*)) (buffer + 3*sizeof(float)*TS*TS); + gshift = (float (*)) (buffer + 4*sizeof(float)*TS*TS); + rbhpfh = (float (*)) (buffer + 5*sizeof(float)*TS*TS); + rbhpfv = (float (*)) (buffer + 6*sizeof(float)*TS*TS); + rblpfh = (float (*)) (buffer + 7*sizeof(float)*TS*TS); + rblpfv = (float (*)) (buffer + 8*sizeof(float)*TS*TS); + grblpfh = (float (*)) (buffer + 9*sizeof(float)*TS*TS); + grblpfv = (float (*)) (buffer + 10*sizeof(float)*TS*TS); + + + if((height+border2)%(TS-border2)==0) vz1=1; else vz1=0; + if((width+border2)%(TS-border2)==0) hz1=1; else hz1=0; + + vblsz=ceil((float)(height+border2)/(TS-border2)+2+vz1); + hblsz=ceil((float)(width+border2)/(TS-border2)+2+hz1); + + //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 + //float blockshifts[1000][3][2]; //fixed memory allocation + //float blockwt[1000]; //fixed memory allocation + + 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))); + + int vctr=0, hctr=0; + + if (cared==0 && cablue==0) { + // Main algorithm: Tile loop + //#pragma omp parallel for shared(image,height,width) private(top,left,indx,indx1) schedule(dynamic) + for (top=-border, vblock=1; top < height; top += TS-border2, vblock++) { + hctr=0; + vctr++; + for (left=-border, hblock=1; left < width; left += TS-border2, hblock++) { + hctr++; + 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(); + // rgb from input CFA data + // rgb values should be floating point number between 0 and 1 + // after white balance multipliers are applied + 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;} + + 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] = (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 && col0.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[j][c]=floor(CAshift[j][c]); + //offset gives NW corner of square containing the min; j=0=vert, 1=hor + + if (fabs(CAshift[j][c])<2.0) { + blockave[j][c] += CAshift[j][c]; + blocksqave[j][c] += SQR(CAshift[j][c]); + blockdenom[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) plistener->setProgress(0.5*fabs((float)top/height)); + + } + } + //end of diagnostic pass + + 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 { + printf ("blockdenom vanishes \n"); + free(buffer1); + return; + } + } + + //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 + for (vblock=1; vblock4.0*blockvar[0][c] || SQR(blockshifts[(vblock)*hblsz+hblock][c][1])>4.0*blockvar[1][c]) continue; + numblox[c] += 1; + 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;} + + + 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[indx1][c] = (rawData[row][col])/65535.0f; + //rgb[indx1][c] = image[indx][c]/65535.0f;//for dcraw implementation + + if ((c&1)==0) rgb[indx1][1] = 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[(rr+shiftvfloor[c])*TS+cc+shifthfloor[c]][1]+(shifthfrac[c])*rgb[(rr+shiftvfloor[c])*TS+cc+shifthceil[c]][1]; + Ginthceil=(1-shifthfrac[c])*rgb[(rr+shiftvceil[c])*TS+cc+shifthfloor[c]][1]+(shifthfrac[c])*rgb[(rr+shiftvceil[c])*TS+cc+shifthceil[c]][1]; + //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]=Gint-rgb[(rr)*TS+cc][c]; + gshift[(rr)*TS+cc]=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[indx][1]-rgb[indx][c]; + + //interpolate color difference from optical R/B locations to grid locations + grbdiffinthfloor=(1-shifthfrac[c]/2)*grbdiff[indx]+(shifthfrac[c]/2)*grbdiff[indx-2*GRBdir[1][c]]; + grbdiffinthceil=(1-shifthfrac[c]/2)*grbdiff[(rr-2*GRBdir[0][c])*TS+cc]+(shifthfrac[c]/2)*grbdiff[(rr-2*GRBdir[0][c])*TS+cc-2*GRBdir[1][c]]; + //grbdiffint is bilinear interpolation of G-R/G-B at grid point + grbdiffint=(1-shiftvfrac[c]/2)*grbdiffinthfloor+(shiftvfrac[c]/2)*grbdiffinthceil; + + //now determine R/B at grid points using interpolated color differences and interpolated G value at grid point + RBint=rgb[indx][1]-grbdiffint; + + if (fabs(RBint-rgb[indx][c])<0.25*(RBint+rgb[indx][c])) { + if (fabs(grbdiffold)>fabs(grbdiffint) ) { + rgb[indx][c]=RBint; + } + } else { + + //gradient weights using difference from G at CA shift points and G at grid points + p[0]=1/(eps+fabs(rgb[indx][1]-gshift[indx])); + p[1]=1/(eps+fabs(rgb[indx][1]-gshift[indx-2*GRBdir[1][c]])); + p[2]=1/(eps+fabs(rgb[indx][1]-gshift[(rr-2*GRBdir[0][c])*TS+cc])); + p[3]=1/(eps+fabs(rgb[indx][1]-gshift[(rr-2*GRBdir[0][c])*TS+cc-2*GRBdir[1][c]])); + + grbdiffint = (p[0]*grbdiff[indx]+p[1]*grbdiff[indx-2*GRBdir[1][c]]+ + p[2]*grbdiff[(rr-2*GRBdir[0][c])*TS+cc]+p[3]*grbdiff[(rr-2*GRBdir[0][c])*TS+cc-2*GRBdir[1][c]])/(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 (fabs(grbdiffold)>fabs(grbdiffint) ) { + rgb[indx][c]=rgb[indx][1]-grbdiffint; + } + } + + //if color difference interpolation overshot the correction, just desaturate + if (grbdiffold*grbdiffint<0) { + rgb[indx][c]=rgb[indx][1]-0.5*(grbdiffold+grbdiffint); + } + } + + // copy CA corrected results back to image matrix + for (rr=border; rr < rr1-border; rr++) + for (row=rr+top, cc=border+(FC(rr,2)&1); cc < cc1-border; cc+=2) { + col = cc + left; + indx = row*width + col; + c = FC(row,col); + + rawData[row][col] = 65535.0f*rgb[(rr)*TS+cc][c] + 0.5f; + //image[indx][c] = CLIP((int)(65535.0*rgb[(rr)*TS+cc][c] + 0.5));//for dcraw implementation + + } + + if(plistener) plistener->setProgress(0.5+0.5*fabs((float)top/height)); + + } + + // clean up + free(buffer); + free(Gtmp); + free(buffer1); + + + +#undef TS +//#undef border +//#undef border2 +#undef PIX_SORT +} + + + diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt new file mode 100644 index 000000000..a58894da7 --- /dev/null +++ b/rtengine/CMakeLists.txt @@ -0,0 +1,35 @@ +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 (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 + stdimagesource.cc myfile.cc iccjpeg.cc hlmultipliers.cc improccoordinator.cc + processingjob.cc rtthumbnail.cc utils.cc labimage.cc slicer.cc + iplab2rgb.cc ipsharpen.cc iptransform.cc ipresize.cc ipvibrance.cc + jpeg_memsrc.cc jdatasrc.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 + 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}) 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..5a69daac1 --- /dev/null +++ b/rtengine/EdgePreservingDecomposition.cc @@ -0,0 +1,461 @@ +#include +#include "rt_math.h" +#include "EdgePreservingDecomposition.h" + +/* 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, unsigned int n, bool OkToModify_b, + float *x, float RMSResidual, void *Pass, unsigned int MaximumIterates, void Preconditioner(float *Product, float *x, void *Pass)){ + unsigned int iterate, i; + + //Start r and x. + float *r = new float[n]; + 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); + for(i = 0; i != n; i++) r[i] = b[i] - r[i]; //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); + } + for(i = 0; i != n; i++) rs += r[i]*s[i]; + + //Search direction d. + float *d = new float[n]; + 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); + for(i = 0; i != n; i++) ab += d[i]*ax[i]; + + 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; + for(i = 0; i != n; i++){ + x[i] += ab*d[i]; + r[i] -= ab*ax[i]; //"Fast recursive formula", use explicit r = b - Ax occasionally? + rms += r[i]*r[i]; + } + rms = sqrtf(rms/n); +//printf("%f\n", rms); + //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; + for(i = 0; i != n; i++) rs += r[i]*s[i]; + ab = rs/ab; + + //Update search direction p. + for(i = 0; i != n; i++) d[i] = s[i] + ab*d[i]; + } + 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; + delete[] r; + delete[] d; + return x; +} + + +MultiDiagonalSymmetricMatrix::MultiDiagonalSymmetricMatrix(unsigned int Dimension, unsigned int NumberOfDiagonalsInLowerTriangle){ + n = Dimension; + m = NumberOfDiagonalsInLowerTriangle; + IncompleteCholeskyFactorization = NULL; + + Diagonals = new float *[m]; + StartRows = new unsigned int [m]; + memset(Diagonals, 0, sizeof(float *)*m); + memset(StartRows, 0, sizeof(unsigned int)*m); +} + +MultiDiagonalSymmetricMatrix::~MultiDiagonalSymmetricMatrix(){ + for(unsigned int i = 0; i != m; i++) delete[] Diagonals[i]; + delete[] Diagonals; + delete[] StartRows; +} + +bool MultiDiagonalSymmetricMatrix::CreateDiagonal(unsigned int index, unsigned int StartRow){ + 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; + } + + delete[] Diagonals[index]; + 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; +} + +int MultiDiagonalSymmetricMatrix::FindIndex(unsigned int StartRow){ + //There's GOT to be a better way to do this. "Bidirectional map?" + for(unsigned int i = 0; i != m; i++) + if(StartRows[i] == StartRow) + return i; + return -1; +} + +bool MultiDiagonalSymmetricMatrix::LazySetEntry(float value, unsigned int row, unsigned 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 *Product, float *x){ + //Initialize to zero. + memset(Product, 0, n*sizeof(float)); + + //Loop over the stored diagonals. + for(unsigned int i = 0; i != m; i++){ + unsigned int sr = StartRows[i]; + float *a = Diagonals[i]; //One fewer dereference. + unsigned int j, l = DiagonalLength(sr); + + if(sr == 0) + for(j = 0; j != l; j++) + Product[j] += a[j]*x[j]; //Separate, fairly simple treatment for the main diagonal. + else + for(j = 0; j != l; j++) + Product[j + sr] += a[j]*x[j], //Contribution from lower... + Product[j] += a[j]*x[j + sr]; //...and upper triangle. + } +} + +bool MultiDiagonalSymmetricMatrix::CreateIncompleteCholeskyFactorization(unsigned int MaxFillAbove){ + if(m == 1){ + printf("Error in MultiDiagonalSymmetricMatrix::CreateIncompleteCholeskyFactorization: just one diagonal? Can you divide?\n"); + return false; + } + if(StartRows[0] != 0){ + printf("Error in MultiDiagonalSymmetricMatrix::CreateIncompleteCholeskyFactorization: main diagonal required to exist for this math.\n"); + return false; + } + + //How many diagonals in the decomposition? + MaxFillAbove++; //Conceptually, now "fill" includes an existing diagonal. Simpler in the math that follows. + unsigned int i, j, mic; + for(mic = i = 1; i != m; i++) + mic += rtengine::min(StartRows[i] - StartRows[i - 1], MaxFillAbove); //Guarunteed positive since StartRows must be created in increasing order. + + //Initialize the decomposition - setup memory, start rows, etc. + MultiDiagonalSymmetricMatrix *ic = new MultiDiagonalSymmetricMatrix(n, mic); + ic->CreateDiagonal(0, 0); //There's always a main diagonal in this type of decomposition. + for(mic = i = 1; i != m; i++){ + //Set j to the number of diagonals to be created corresponding to a diagonal on this source matrix... + j = rtengine::min(StartRows[i] - StartRows[i - 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[i] - 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; + unsigned int k, MaxStartRow = StartRows[m - 1]; //Handy number. + float **l = ic->Diagonals; + float *d = ic->Diagonals[0]; //Describes D in LDLt. + + //Loop over the columns. + for(j = 0; j != n; j++){ + //Calculate d for this column. + d[j] = Diagonals[0][j]; + + //This is a loop over k from 1 to j, inclusive. We'll cover that by looping over the index of the diagonals (s), and get k from it. + //The first diagonal is d (k = 0), so skip that and have s start at 1. Cover all available s but stop if k exceeds j. + for(s = 1; s != ic->m; s++){ + k = ic->StartRows[s]; + if(k > j) break; + d[j] -= l[s][j - k]*l[s][j - k]*d[j - k]; + } + + if(d[j] == 0.0f){ + printf("Error in MultiDiagonalSymmetricMatrix::CreateIncompleteCholeskyFactorization: division by zero. Matrix not decomposable.\n"); + delete ic; + return false; + } + float id = 1.0f/d[j]; + + //Now, calculate l from top down along this column. + for(s = 1; s != ic->m; s++){ + i = ic->StartRows[s]; //Start row for this entry. + if(j >= ic->n - i) break; //Possible values of j are limited. + + //Quicker access for an element of l. + float *lij = &l[s][j]; + sss = FindIndex(i); //Find element in same spot in the source matrix. It might be a zero. + *lij = sss < 0 ? 0.0f : Diagonals[sss][j]; + + //Similar to the loop involving d, convoluted by the fact that two l are involved. + for(ss = 1; ss != ic->m; ss++){ + k = ic->StartRows[ss]; + if(k > j) break; + if(i + k > MaxStartRow) break; //Quick exit once k to big. + + int sss = ic->FindIndex(i + k); + if(sss < 0) continue; //Asked for diagonal nonexistant. But there may be something later, so don't break. + + /* Let's think about the factors in the term below for a moment. + j varies from 0 to n - 1, so j - k is bounded inclusive by 0 and j - 1. So d[j - k] is always in the matrix. + + l[sss] and l[ss] are diagonals with corresponding start rows i + k and k. + For l[sss][j - k] to exist, we must have j - k < n - (i + k) -> j < n - i, which was checked outside this loop and true at this point. + For l[ ss][j - k] to exist, we must have j - k < n - k -> j < n, which is true straight from definition. + + So, no additional checks, all is good and within bounds at this point.*/ + *lij -= l[sss][j - k]*l[ss][j - k]*d[j - k]; + } + + *lij *= id; + } + } + + IncompleteCholeskyFactorization = ic; + return true; +} + +void MultiDiagonalSymmetricMatrix::KillIncompleteCholeskyFactorization(void){ + delete IncompleteCholeskyFactorization; +} + +void MultiDiagonalSymmetricMatrix::CholeskyBackSolve(float *x, float *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 *y = new float[n]; + float **d = IncompleteCholeskyFactorization->Diagonals; + unsigned int *s = IncompleteCholeskyFactorization->StartRows; + unsigned int M = IncompleteCholeskyFactorization->m, N = IncompleteCholeskyFactorization->n; + unsigned int i, j; + for(j = 0; j != N; j++){ + y[j] = b[j]; + + for(i = 1; i != M; i++){ //Start at 1 because zero is D. + int c = (int)j - (int)s[i]; + if(c < 0) break; //Due to ordering of StartRows, no further contributions. + y[j] -= d[i][c]*y[c]; + } + } + + //Now, solve x from D Lt x = y -> Lt x = D^-1 y + while(j-- != 0){ + x[j] = y[j]/d[0][j]; + + for(i = 1; i != M; i++){ + if(j + s[i] >= N) break; + x[j] -= d[i][j]*x[j + s[i]]; + } + } + + delete[] y; +} + + + + +EdgePreservingDecomposition::EdgePreservingDecomposition(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 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; +} + +float *EdgePreservingDecomposition::CreateBlur(float *Source, float Scale, float EdgeStopping, unsigned 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 *a, *g; + if(UseBlurForEdgeStop) a = new float[n], g = Blur; + else a = Blur, g = Source; + + unsigned int x, y, i; + unsigned int w1 = w - 1, h1 = h - 1; + float eps = 0.02f; + 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 = (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*powf(0.5f*sqrtf(gx*gx + gy*gy + eps*eps), -EdgeStopping); + } + } + + /* 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)); + 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. + 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, unsigned int Iterates, unsigned 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(unsigned int i = 0; i != Reweightings; i++) + CreateBlur(Source, Scale, EdgeStopping, Iterates, Blur, true); + + return Blur; +} + +float *EdgePreservingDecomposition::CompressDynamicRange(float *Source, float Scale, float EdgeStopping, float CompressionExponent, float DetailBoost, unsigned int Iterates, unsigned 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. + unsigned int i; + for(i = 0; i != n; i++) + Source[i] = logf(Source[i] + eps); + + //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. + for(i = 0; i != n; i++){ + float ce = expf(Source[i] + u[i]*(CompressionExponent - 1.0f)) - eps; + float ue = expf(u[i]) - eps; + Source[i] = expf(Source[i]) - eps; + Compressed[i] = ce + DetailBoost*(Source[i] - ue); + } + + if(Compressed != u) delete[] u; + return Compressed; +} + diff --git a/rtengine/EdgePreservingDecomposition.h b/rtengine/EdgePreservingDecomposition.h new file mode 100644 index 000000000..b3b832823 --- /dev/null +++ b/rtengine/EdgePreservingDecomposition.h @@ -0,0 +1,135 @@ +#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 + + +//This is for solving big symmetric positive definite linear problems. +float *SparseConjugateGradient(void Ax(float *Product, float *x, void *Pass), float *b, unsigned int n, bool OkToModify_b = true, float *x = NULL, float RMSResidual = 0.0f, void *Pass = NULL, unsigned 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(unsigned int Dimension, unsigned 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; + unsigned int *StartRows; + bool CreateDiagonal(unsigned int index, unsigned int StartRow); + unsigned 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 unsigned int DiagonalLength(unsigned 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, unsigned int row, unsigned 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. + int FindIndex(unsigned int StartRow); + + //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(unsigned 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(unsigned int width, unsigned 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, 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 Scale, float EdgeStopping, 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 Scale = 1.0f, float EdgeStopping = 1.4f, 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/FTblockDN.cc b/rtengine/FTblockDN.cc new file mode 100644 index 000000000..d741e0428 --- /dev/null +++ b/rtengine/FTblockDN.cc @@ -0,0 +1,983 @@ +//////////////////////////////////////////////////////////////// +// +// 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 "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" + +#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. + + */ + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + + + + void ImProcFunctions::RGB_denoise(Imagefloat * src, Imagefloat * dst, bool isRAW, const procparams::DirPyrDenoiseParams & dnparams, const procparams::DefringeParams & defringe) + { + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + /*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; + } + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // gamma transform for input data + float gam = dnparams.gamma; + float gamthresh = 0.001; + float gamslope = exp(log((double)gamthresh)/gam)/gamthresh; + + LUTf gamcurve(65536,0); + + for (int i=0; i<65536; i++) { + gamcurve[i] = (Color::gamma((double)i/65535.0, gam, gamthresh, gamslope, 1.0, 0.0)) * 32768.0f; + } + + // inverse gamma transform for output data + float igam = 1/gam; + float igamthresh = gamthresh*gamslope; + float igamslope = 1/gamslope; + + LUTf igamcurve(65536,0); + + for (int i=0; i<65536; i++) { + igamcurve[i] = (Color::gamma((float)i/32768.0f, igam, igamthresh, igamslope, 1.0, 0.0) * 65535.0f); + } + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + //srand((unsigned)time(0));//test with random data + + const float gain = pow (2.0, dnparams.expcomp); + + float noisevar_Ldetail = SQR((SQR(100-dnparams.Ldetail) + 50*(100-dnparams.Ldetail)) * TS * 0.5f); + + + 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 Lin(width,height,ARRAY2D_CLEAR_DATA); + //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 + 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*/; ir[i][j] ]; + float gtmp = Color::igammatab_srgb[ src->g[i][j] ]; + float btmp = Color::igammatab_srgb[ src->b[i][j] ]; + + //perhaps use LCH or YCrCb ??? + float X = xyz_sRGB[0][0]*rtmp + xyz_sRGB[0][1]*gtmp + xyz_sRGB[0][2]*btmp; + float Y = xyz_sRGB[1][0]*rtmp + xyz_sRGB[1][1]*gtmp + xyz_sRGB[1][2]*btmp; + float Z = xyz_sRGB[2][0]*rtmp + xyz_sRGB[2][1]*gtmp + xyz_sRGB[2][2]*btmp; + + 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; + } + } + } + + + //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. + wavelet_decomposition Ldecomp(labdn->data, labdn->W, labdn->H, 5/*maxlevels*/, 0/*subsampling*/ ); + wavelet_decomposition adecomp(labdn->data+datalen, labdn->W, labdn->H, 5, 1 ); + wavelet_decomposition bdecomp(labdn->data+2*datalen, labdn->W, labdn->H, 5, 1 ); + + float noisevarL = SQR((dnparams.luma/125.0f)*(1+ dnparams.luma/25.0f)); + float noisevarab = SQR(dnparams.chroma/10.0f); + + //WaveletDenoiseAll_BiShrink(Ldecomp, adecomp, bdecomp, noisevarL, noisevarab); + WaveletDenoiseAll(Ldecomp, adecomp, bdecomp, noisevarL, noisevarab); + + Ldecomp.reconstruct(labdn->data); + adecomp.reconstruct(labdn->data+datalen); + bdecomp.reconstruct(labdn->data+2*datalen); + + //TODO: at this point wavelet coefficients storage can be freed + + //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! + + + // allocate DCT data structures + + // 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 + + //DCT block data storage + float * Lblox = (float *) fftwf_malloc (numblox_W*TS*TS * sizeof (float)); + float * fLblox = (float *) fftwf_malloc (numblox_W*TS*TS * sizeof (float)); + + + //make a plan for FFTW + fftwf_plan plan_forward_blox, plan_backward_blox; + + int nfwd[2]={TS,TS}; + + //for DCT: + const fftw_r2r_kind fwdkind[2] = {FFTW_REDFT10, FFTW_REDFT10}; + const fftw_r2r_kind bwdkind[2] = {FFTW_REDFT01, FFTW_REDFT01}; + + plan_forward_blox = fftwf_plan_many_r2r(2, nfwd, numblox_W, Lblox, NULL, 1, TS*TS, fLblox, NULL, 1, TS*TS, fwdkind, FFTW_ESTIMATE ); + plan_backward_blox = fftwf_plan_many_r2r(2, nfwd, numblox_W, fLblox, NULL, 1, TS*TS, Lblox, NULL, 1, TS*TS, bwdkind, FFTW_ESTIMATE ); + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // Main detail recovery algorithm: Block loop + //OpenMP here + //adding omp here leads to artifacts + 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]; + float * Hmask = new float [width]; + + for (int i=0; i0) Vmask[i] = mask; + if (tilebottom0) Hmask[i] = mask; + if (tilerightL[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]; + 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]; + + float rtmp = sRGB_xyz[0][0]*X + sRGB_xyz[0][1]*Y + sRGB_xyz[0][2]*Z; + float gtmp = sRGB_xyz[1][0]*X + sRGB_xyz[1][1]*Y + sRGB_xyz[1][2]*Z; + float btmp = sRGB_xyz[2][0]*X + sRGB_xyz[2][1]*Y + sRGB_xyz[2][2]*Z; + + dsttmp->r[i][j] += factor*rtmp; + dsttmp->g[i][j] += factor*gtmp; + dsttmp->b[i][j] += factor*btmp; + + } + } + } + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + delete labdn; + delete[] Vmask; + delete[] Hmask; + + }//end of tile row + }//end of tile loop + + //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; + + }//end of main RGB_denoise + + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + + void ImProcFunctions::RGBtile_denoise (float * fLblox, int vblproc, int hblproc, int numblox_H, int numblox_W, float noisevar_Ldetail ) //for DCT + { + 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 + + 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); + AlignedBuffer* buffer = new AlignedBuffer (MAX(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_ab*mada[lvl][dir-1]; + float mad_b = noisevar_ab*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_ab>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-exp(-(mag_a/mad_a)-(mag_L/(9*mad_L)))/*satfactor_a*/); + WavCoeffs_b[dir][coeffloc_ab] *= SQR(1-exp(-(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; i0.01) { +//OpenMP here + +#ifdef _OPENMP +#pragma omp parallel for +#endif + for (int i=0; i2*thresh_a ? 1 : (coeff_a2*thresh_b ? 1 : (coeff_b0.01) { +//OpenMP here +#ifdef _OPENMP +#pragma omp parallel for +#endif + 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 + +#include +#ifndef NDEBUG +#include +#endif + +template +class LUT { +private: + // list of variables ordered to improve cache speed + unsigned int maxs; + T * data; + unsigned int clip, size, owner; +public: + LUT(int s, int flags = 0xfffffff) { + clip = flags; + data = new T[s]; + owner = 1; + size = s; + maxs=size-2; + } + void operator ()(int s, int flags = 0xfffffff) { + if (owner&&data) + delete[] data; + clip = flags; + data = new T[s]; + owner = 1; + size = s; + maxs=size-2; + } + + LUT(int s, T * source, int flags = 0xfffffff) { + clip = flags; + data = new T[s]; + owner = 1; + size = s; + maxs=size-2; + for (int i = 0; i < s; i++) { + data[i] = source[i]; + } + } + + LUT(void) { + data = NULL; + reset(); + } + + ~LUT() { + if (owner) + delete[] data; + } + + void setClip(int flags) { + clip = flags; + } + + LUT & operator=(const 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; + } + + 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) { + memset(data, 0, size * sizeof(T)); + } + + void reset(void) { + delete[] data; + 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..ed8f623c7 --- /dev/null +++ b/rtengine/PF_correct_RT.cc @@ -0,0 +1,130 @@ +//////////////////////////////////////////////////////////////// +// +// Chromatic Aberration Auto-correction +// +// copyright (c) 2008-2010 Emil Martinec +// +// +// code dated: November 24, 2010 +// +// 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" + +#ifdef _OPENMP +#include +#endif + +#include "rt_math.h" + +using namespace std; + +namespace rtengine { + +void ImProcFunctions::PF_correct_RT(LabImage * src, LabImage * dst, double radius, int thresh) { + int halfwin = ceil(2*radius)+1; + +#include "rt_math.h" + + // local variables + int width=src->W, height=src->H; + //temporary array to store chromaticity + int (*fringe); + fringe = (int (*)) calloc ((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); + + gaussHorizontal (src->L, tmp1->L, buffer, src->W, src->H, radius); + gaussVertical (tmp1->L, tmp1->L, buffer, src->W, src->H, radius); + } + +//#ifdef _OPENMP +//#pragma omp parallel for +//#endif + float chromave=0; + for(int i = 0; i < height; i++ ) { + for(int j = 0; j < width; j++) { + float chroma = SQR(src->a[i][j]-tmp1->a[i][j])+SQR(src->b[i][j]-tmp1->b[i][j]); + chromave += chroma; + fringe[i*width+j]=chroma; + } + } + chromave /= (height*width); + +#ifdef _OPENMP +#pragma omp parallel for +#endif + + for(int i = 0; i < height; i++ ) { + for(int j = 0; 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 (33*fringe[i*width+j]>thresh*chromave) { + float atot=0; + float btot=0; + float norm=0; + float wt; + for (int i1=max(0,i-halfwin+1); i1a[i1][j1]; + btot += wt*src->b[i1][j1]; + norm += wt; + } + tmp1->a[i][j] = (int)(atot/norm); + tmp1->b[i][j] = (int)(btot/norm); + }//end of ab channel averaging + } + } + +#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]; + dst->a[i][j] = tmp1->a[i][j]; + dst->b[i][j] = tmp1->b[i][j]; + } + } + + delete tmp1; + free(fringe); +} + +} + diff --git a/rtengine/alignedbuffer.h b/rtengine/alignedbuffer.h new file mode 100644 index 000000000..057b654ad --- /dev/null +++ b/rtengine/alignedbuffer.h @@ -0,0 +1,86 @@ +/* + * This file is part of RawTherapee. + * +* Copyright (c) 2004-2012 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 . + */ +#ifndef _ALIGNEDBUFFER_ +#define _ALIGNEDBUFFER_ +#include +#include +#include + +// Aligned buffer that should be faster +template class AlignedBuffer { + + private: + T* real ; + + public: + T* data ; + bool inUse; + + AlignedBuffer (size_t size, size_t align=16) { + real = new T[size+2*align]; + data = (T*)((uintptr_t)real + (align-((uintptr_t)real)%align)); + inUse=true; + } + + ~AlignedBuffer () { + delete [] real; + } +}; + +// Multi processor version, use with OpenMP +template class AlignedBufferMP { +private: + Glib::Mutex mtx; + std::vector*> buffers; + size_t size; + +public: + AlignedBufferMP(size_t sizeP) { + size=sizeP; + } + + ~AlignedBufferMP() { + for (int i=0;i* acquire() { + Glib::Mutex::Lock 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) { + Glib::Mutex::Lock 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..5c4f3f7a8 --- /dev/null +++ b/rtengine/amaze_demosaic_RT.cc @@ -0,0 +1,980 @@ +//////////////////////////////////////////////////////////////// +// +// 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" + +using namespace rtengine; + +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; + +#define TS 512 // Tile size; the image is processed in square tiles to lower memory requirements and facilitate multi-threading + + // 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; + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +#pragma omp parallel +{ + //position of top/left corner of the tile + int top, left; + // beginning of storage block for tile + char *buffer; + // rgb values + float (*rgb)[3]; + // horizontal gradient + float (*delh); + // vertical gradient + float (*delv); + // square of delh + float (*delhsq); + // square of delv + float (*delvsq); + // gradient based directional weights for interpolation + float (*dirwts)[2]; + // 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)[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 curvature of interpolated G (used to refine interpolation in Nyquist texture regions) + float (*Dgrbh2); + // vertical curvature of interpolated G + float (*Dgrbv2); + // 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); + // 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 plus direction + float (*rbp); + // interpolated color difference R-B in minus direction + float (*rbm); + + // nyquist texture flag 1=nyquist, 0=not nyquist + int (*nyquist); + + + // assign working space + buffer = (char *) malloc((32*sizeof(float)+sizeof(int))*TS*TS); + //merror(buffer,"amaze_interpolate()"); + //memset(buffer,0,(34*sizeof(float)+sizeof(int))*TS*TS); + // rgb array + rgb = (float (*)[3]) buffer; //pointers to array + delh = (float (*)) (buffer + 3*sizeof(float)*TS*TS); + delv = (float (*)) (buffer + 4*sizeof(float)*TS*TS); + delhsq = (float (*)) (buffer + 5*sizeof(float)*TS*TS); + delvsq = (float (*)) (buffer + 6*sizeof(float)*TS*TS); + dirwts = (float (*)[2]) (buffer + 7*sizeof(float)*TS*TS); + vcd = (float (*)) (buffer + 9*sizeof(float)*TS*TS); + hcd = (float (*)) (buffer + 10*sizeof(float)*TS*TS); + vcdalt = (float (*)) (buffer + 11*sizeof(float)*TS*TS); + hcdalt = (float (*)) (buffer + 12*sizeof(float)*TS*TS); + cddiffsq = (float (*)) (buffer + 13*sizeof(float)*TS*TS); + hvwt = (float (*)) (buffer + 14*sizeof(float)*TS*TS); + Dgrb = (float (*)[2]) (buffer + 15*sizeof(float)*TS*TS); + delp = (float (*)) (buffer + 17*sizeof(float)*TS*TS); + delm = (float (*)) (buffer + 18*sizeof(float)*TS*TS); + rbint = (float (*)) (buffer + 19*sizeof(float)*TS*TS); + Dgrbh2 = (float (*)) (buffer + 20*sizeof(float)*TS*TS); + Dgrbv2 = (float (*)) (buffer + 21*sizeof(float)*TS*TS); + dgintv = (float (*)) (buffer + 22*sizeof(float)*TS*TS); + dginth = (float (*)) (buffer + 23*sizeof(float)*TS*TS); + Dgrbp1 = (float (*)) (buffer + 24*sizeof(float)*TS*TS); + Dgrbm1 = (float (*)) (buffer + 25*sizeof(float)*TS*TS); + Dgrbpsq1 = (float (*)) (buffer + 26*sizeof(float)*TS*TS); + Dgrbmsq1 = (float (*)) (buffer + 27*sizeof(float)*TS*TS); + cfa = (float (*)) (buffer + 28*sizeof(float)*TS*TS); + pmwt = (float (*)) (buffer + 29*sizeof(float)*TS*TS); + rbp = (float (*)) (buffer + 30*sizeof(float)*TS*TS); + rbm = (float (*)) (buffer + 31*sizeof(float)*TS*TS); + + nyquist = (int (*)) (buffer + 32*sizeof(int)*TS*TS); + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + /*double dt; + clock_t t1, t2; + + clock_t t1_init, t2_init = 0; + clock_t t1_vcdhcd, t2_vcdhcd = 0; + clock_t t1_cdvar, t2_cdvar = 0; + clock_t t1_nyqtest, t2_nyqtest = 0; + clock_t t1_areainterp, t2_areainterp = 0; + clock_t t1_compare, t2_compare = 0; + clock_t t1_diag, t2_diag = 0; + clock_t t1_chroma, t2_chroma = 0;*/ + + + // start + //if (verbose) fprintf (stderr,_("AMaZE interpolation ...\n")); + //t1 = clock(); + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + if (plistener) { + plistener->setProgressStr ("AMaZE Demosaicing..."); + plistener->setProgress (0.0); + } + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + //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 +#pragma omp for schedule(dynamic) nowait + for (top=winy-16; top < winy+height; top += TS-32) + for (left=winx-16; left < winx+width; left += TS-32) { + //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; + // +1 or -1 + int sgn; + + //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; + //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; + //adaptive interpolation weight using difference of left-right and up-down G interpolations + float diffwt; + //alternative adaptive weight for combining horizontal/vertical interpolations + float hvwtalt; + //temporary variables for combining interpolation weights at R and B sites + float vo, ve; + //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; + //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; + //variance of R-B in plus/minus directions + float rbvarp, rbvarm; + + + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + // 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;} + + for (rr=rrmin; rr < rrmax; rr++) + for (row=rr+top, cc=ccmin; cc < ccmax; cc++) { + col = cc+left; + c = FC(rr,cc); + indx1=rr*TS+cc; + rgb[indx1][c] = (rawData[row][col])/65535.0f; + //indx=row*width+col; + //rgb[indx1][c] = image[indx][c]/65535.0f;//for dcraw implementation + + cfa[indx1] = rgb[indx1][c]; + } + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //fill borders + if (rrmin>0) { + for (rr=0; rr<16; rr++) + for (cc=ccmin; cc0) { + for (rr=rrmin; rr0 && ccmin>0) { + for (rr=0; rr<16; rr++) + for (cc=0; cc<16; cc++) { + c=FC(rr,cc); + rgb[(rr)*TS+cc][c] = (rawData[winy+32-rr][winx+32-cc])/65535.0f; + //rgb[(rr)*TS+cc][c] = (rgb[(32-rr)*TS+(32-cc)][c]);//for dcraw implementation + cfa[(rr)*TS+cc] = rgb[(rr)*TS+cc][c]; + } + } + if (rrmax0 && ccmax0) { + for (rr=0; rr<16; rr++) + for (cc=0; cc<16; cc++) { + c=FC(rr,cc); + rgb[(rrmax+rr)*TS+cc][c] = (rawData[(winy+height-rr-2)][(winx+32-cc)])/65535.0f; + //rgb[(rrmax+rr)*TS+cc][c] = (image[(height-rr-2)*width+(32-cc)][c])/65535.0f;//for dcraw implementation + cfa[(rrmax+rr)*TS+cc] = rgb[(rrmax+rr)*TS+cc][c]; + } + } + + //end of border fill + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + for (rr=1; rr < rr1-1; rr++) + for (cc=1, indx=(rr)*TS+cc; cc < cc1-1; cc++, indx++) { + + delh[indx] = fabs(cfa[indx+1]-cfa[indx-1]); + delv[indx] = fabs(cfa[indx+v1]-cfa[indx-v1]); + delhsq[indx] = SQR(delh[indx]); + delvsq[indx] = SQR(delv[indx]); + delp[indx] = fabs(cfa[indx+p1]-cfa[indx-p1]); + delm[indx] = fabs(cfa[indx+m1]-cfa[indx-m1]); + + } + + for (rr=2; rr < rr1-2; rr++) + for (cc=2,indx=(rr)*TS+cc; cc < cc1-2; cc++, indx++) { + + dirwts[indx][0] = eps+delv[indx+v1]+delv[indx-v1]+delv[indx];//+fabs(cfa[indx+v2]-cfa[indx-v2]); + //vert directional averaging weights + dirwts[indx][1] = eps+delh[indx+1]+delh[indx-1]+delh[indx];//+fabs(cfa[indx+2]-cfa[indx-2]); + //horizontal weights + + if (FC(rr,cc)&1) { + //for later use in diagonal interpolation + //Dgrbp1[indx]=2*cfa[indx]-(cfa[indx-p1]+cfa[indx+p1]); + //Dgrbm1[indx]=2*cfa[indx]-(cfa[indx-m1]+cfa[indx+m1]); + Dgrbpsq1[indx]=(SQR(cfa[indx]-cfa[indx-p1])+SQR(cfa[indx]-cfa[indx+p1])); + Dgrbmsq1[indx]=(SQR(cfa[indx]-cfa[indx-m1])+SQR(cfa[indx]-cfa[indx+m1])); + } + } + + //t2_init += clock()-t1_init; + // end of tile initialization + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + //interpolate vertical and horizontal color differences + //t1_vcdhcd = clock(); + + for (rr=4; rr 0.8*clip_pt || Gintvha > 0.8*clip_pt || Ginthha > 0.8*clip_pt) { + //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)); + + } + //t2_vcdhcd += clock() - t1_vcdhcd; + + //t1_cdvar = clock(); + 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]); + } + + for (rr=6; rr0 && fabs(0.5-diffwt)0) {nyquist[indx]=1;}//nyquist=1 for nyquist region + } + + for (rr=8; rr4) nyquist[indx]=1; + //or not + if (areawt<4) nyquist[indx]=0; + } + + //t2_nyqtest += clock() - t1_nyqtest; + // end of Nyquist test + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // in areas of Nyquist texture, do area interpolation + //t1_areainterp = clock(); + for (rr=8; rr0.5) Dgrb[indx][0]=vcd[indx]; + rgb[indx][1] = cfa[indx] + Dgrb[indx][0];//evaluate G (finally!) + + //local curvature in G (preparation for nyquist refinement step) + if (nyquist[indx]) { + Dgrbh2[indx] = SQR(rgb[indx][1] - 0.5*(rgb[indx-1][1]+rgb[indx+1][1])); + Dgrbv2[indx] = SQR(rgb[indx][1] - 0.5*(rgb[indx-v1][1]+rgb[indx+v1][1])); + } else { + Dgrbh2[indx] = Dgrbv2[indx] = 0; + } + } + + //end of standard interpolation + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // refine Nyquist areas using G curvatures + + for (rr=8; rr clip_pt) rbp[indx]=ULIM(rbp[indx],cfa[indx-p1],cfa[indx+p1]);//for RT implementation + if (rbm[indx] > clip_pt) rbm[indx]=ULIM(rbm[indx],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 + } + + + + for (rr=10; rr 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]); + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + rgb[indx][1] = Ginth*(1.0f-hvwt[indx]) + Gintv*hvwt[indx]; + //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[indx][0] = rgb[indx][1]-cfa[indx]; + + //rgb[indx][2-FC(rr,cc)]=2*rbint[indx]-cfa[indx]; + } + //end of diagonal interpolation correction + //t2_diag += clock() - t1_diag; + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + //t1_chroma = clock(); + //fancy chrominance interpolation + //(ey,ex) is location of R site + for (rr=13-ey; rr1.0) + { + progress=1.0; + } + if(plistener) plistener->setProgress(progress); + } + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + + // clean up + free(buffer); +} + // done + +#undef TS + +} diff --git a/rtengine/array2D.h b/rtengine/array2D.h new file mode 100644 index 000000000..b80f1d1e8 --- /dev/null +++ b/rtengine/array2D.h @@ -0,0 +1,271 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2011 Jan Rinze Peterzon (janrinze@gmail.com) + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ + +/* + * Declaration of flexible 2D arrays + * + * Usage: + * + * array2D name (X-size,Y-size); + * array2D name (X-size,Y-size type ** data); + * + * creates an array which is valid within the normal C/C++ scope "{ ... }" + * + * access to elements is a simple as: + * + * array2D my_array (10,10); // creates 10x10 array of floats + * value = my_array[3][5]; + * my_array[4][6]=value; + * + * or copy an existing 2D array + * + * float ** mydata; + * array2D my_array (10,10,mydata); + * + * + * Useful extra pointers + * + * ** my_array gives access to the pointer for access with [][] + * * my_array gives access to the flat stored data. + * + * Advanced usage: + * array2D my_array ; // empty container. + * my_array(10,10) ; // resize to 10x10 array + * my_array(10,10,ARRAY2D_CLEAR_DATA) ; // resize to 10x10 and clear data + * my_array(10,10,ARRAY2D_CLEAR_DATA|ARRAY2D_LOCK_DATA) ; same but set a lock on changes + * + * !! locked arrays cannot be resized and cannot be unlocked again !! + */ +#ifndef ARRAY2D_H_ +#define ARRAY2D_H_ +#include // for raise() +#include + +// flags for use +#define ARRAY2D_LOCK_DATA 1 +#define ARRAY2D_CLEAR_DATA 2 +#define ARRAY2D_BYREFERENCE 4 +#define ARRAY2D_VERBOSE 8 + +#include +#include + +template +class array2D { + +private: + int x, y, owner, flags; + T ** ptr; + T * data; + bool lock; // useful lock to ensure data is not changed anymore. + void ar_realloc(int w, int h) { + if ((ptr) && ((h > y) || (4 * h < y))) { + delete[] ptr; + ptr = NULL; + } + if ((data) && (((h * w) > (x * y)) || ((h * w) < ((x * y) / 4)))) { + delete[] data; + data = NULL; + } + if (ptr == NULL) + ptr = new T*[h]; + if (data == NULL) + data = new T[h * w]; + + x = w; + y = h; + for (int i = 0; i < h; i++) + ptr[i] = data + w * i; + owner = 1; + } +public: + + // use as empty declaration, resize before use! + // very useful as a member object + array2D() : + x(0), y(0), owner(0), ptr(NULL), data(NULL), lock(0) { + //printf("got empty array2D init\n"); + } + + // creator type1 + array2D(int w, int h, unsigned int flgs = 0) { + flags = flgs; + lock = flags & ARRAY2D_LOCK_DATA; + data = new T[h * w]; + owner = 1; + x = w; + y = h; + ptr = new T*[h]; + for (int i = 0; i < h; i++) + ptr[i] = data + i * w; + if (flags & ARRAY2D_CLEAR_DATA) + memset(data, 0, w * h * sizeof(T)); + } + + // creator type 2 + array2D(int w, int h, T ** source, unsigned int flgs = 0) { + flags = flgs; + //if (lock) { printf("array2D attempt to overwrite data\n");raise(SIGSEGV);} + lock |= flags & ARRAY2D_LOCK_DATA; + // when by reference + // TODO: improve this code with ar_realloc() + owner = (flags & ARRAY2D_BYREFERENCE) ? 0 : 1; + if (owner) + data = new T[h * w]; + else + data = NULL; + x = w; + y = h; + ptr = new T*[h]; + for (int i = 0; i < h; i++) { + if (owner) { + ptr[i] = data + i * w; + for (int j = 0; j < w; j++) + ptr[i][j] = source[i][j]; + } else + ptr[i] = source[i]; + } + } + + // destructor + ~array2D() { + + if (flags & ARRAY2D_VERBOSE) + printf(" deleting array2D size %dx%d \n", x, y); + + if ((owner) && (data)) + delete[] data; + if (ptr) + delete[] ptr; + } + + // use with indices + T * operator[](int index) { + assert((index>=0) && (index < y)); + return ptr[index]; + } + + // use as pointer to T** + operator T**() { + return ptr; + } + + // use as pointer to data + operator T*() { + // only if owner this will return a valid pointer + return data; + } + + + // useful within init of parent object + // or use as resize of 2D array + void operator()(int w, int h, unsigned int flgs = 0) { + flags = flgs; + if (flags & ARRAY2D_VERBOSE) { + printf("got init request %dx%d flags=%u\n", w, h, flags); + printf("previous was data %p ptr %p \n", data, ptr); + } + if (lock) // our object was locked so don't allow a change. + { + printf("got init request but object was locked!\n"); + raise( SIGSEGV); + } + lock = flags & ARRAY2D_LOCK_DATA; + + ar_realloc(w,h); + if (flags & ARRAY2D_CLEAR_DATA) + memset(data, 0, w * h * sizeof(T)); + } + + // import from flat data + void operator()(int w, int h, T* copy, unsigned int flgs = 0) { + flags = flgs; + if (flags & ARRAY2D_VERBOSE) { + printf("got init request %dx%d flags=%u\n", w, h, flags); + printf("previous was data %p ptr %p \n", data, ptr); + } + if (lock) // our object was locked so don't allow a change. + { + printf("got init request but object was locked!\n"); + raise( SIGSEGV); + } + lock = flags & ARRAY2D_LOCK_DATA; + + ar_realloc(w,h); + memcpy(data, copy, w * h * sizeof(T)); + } + int width() { + return x; + } + int height() { + return y; + } + + operator bool() { + return (x > 0 && y > 0); + } + + array2D & operator=( array2D & rhs) { + if (this != &rhs) + + { + if (!owner) // we can only copy same size data + { + if ((x != rhs.x) || (y != rhs.y)) { + printf(" assignment error in array2D\n"); + printf(" sizes differ and not owner\n"); + raise( SIGSEGV); + } + + } else { + ar_realloc(rhs.x, rhs.y); + } + // we could have been created from a different + // array format where each row is created by 'new' + for (int i=0;i +class multi_array2D { +private: + array2D list[num]; + +public: + multi_array2D(int x, int y, int flags = 0) { + for (size_t i = 0; i < num; i++) + list[i](x, y, flags); + } + + ~multi_array2D() { + //printf("trying to delete the list of array2D objects\n"); + } + + array2D & operator[](int index) { + if (static_cast(index) >= num) { + printf("index %0u is out of range[0..%0lu]", index, num - 1); + raise( SIGSEGV); + } + return list[index]; + } +}; +#endif /* array2D_H_ */ diff --git a/rtengine/bilateral2.h b/rtengine/bilateral2.h new file mode 100644 index 000000000..d80dfcd21 --- /dev/null +++ b/rtengine/bilateral2.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 _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 MAXVAL 65535.0 +#define CLIP(a) ((a)>0.0?((a) 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" +//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 void boxblur (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) { + 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 void boxabsblur (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 + +#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/cfa_linedn_RT.cc b/rtengine/cfa_linedn_RT.cc new file mode 100644 index 000000000..1a55f0866 --- /dev/null +++ b/rtengine/cfa_linedn_RT.cc @@ -0,0 +1,448 @@ +//////////////////////////////////////////////////////////////// +// +// CFA line denoise by DCT filtering +// +// copyright (c) 2008-2010 Emil Martinec +// +// +// 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 512 // Tile size + +#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 + + + float aarr[4][8][8], *bbrr[4][8], **dctblock[4]; + for (int j=0; j<4; j++) { + for (int i = 0; i < 8; i++) + bbrr[j][i] = aarr[j][i]; + dctblock[j] = bbrr[j]; + } + + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + 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 + volatile double progress = 0.0; + +#pragma omp parallel + { + + float *cfain= new float[TS*TS]; + float *cfablur= new float[TS*TS]; + float *cfadiff= new float[TS*TS]; + float *cfadn= new float[TS*TS]; + +/* + char *buffer; // TS*TS*16 + float (*cfain); // TS*TS*4 + float (*cfablur); // TS*TS*4 + float (*cfadiff); // TS*TS*4 + float (*cfadn); // TS*TS*4 + buffer = (char *) calloc((3*sizeof(float)+sizeof(int))*TS*TS,1);// 16 +// merror(buffer,"cfa_linedn()"); +// memset(buffer,0,16*TS*TS); + cfain = (float (*)) buffer; //pointers to rows of array + cfablur = (float (*)) (buffer + sizeof(float)*TS*TS); //4 + cfadiff = (float (*)) (buffer + 2*sizeof(float)*TS*TS);//8 + cfadn = (float (*)) (buffer + 3*sizeof(float)*TS*TS);//12 +*/ + // Main algorithm: Tile loop +#pragma omp for schedule(dynamic) nowait + for (int top=0; top < height-16; top += TS-32) + for (int left=0; left < width-16; left += TS-32) { + + int bottom = min(top+TS,height); + int right = min(left+TS, width); + int numrows = bottom - top; + int numcols = right - left; + int indx1; + // load CFA data; data should be in linear gamma space, before white balance multipliers are applied + for (int rr=top; rr < top+numrows; rr++) + for (int cc=left, indx=(rr-top)*TS; cc < left+numcols; cc++, indx++) { + + cfain[indx] = rawData[rr][cc]; + } + //pad the block to a multiple of 16 on both sides + + if (numcols < TS) { + indx1=numcols % 16; + for (int i=0; i<(16-indx1); i++) + for (int rr=0; rr(linehvar[0]+linehvar[1])) {//horizontal lines + for (int i=1; i<8; i++) { + dctblock[0][0][i] *= 0.5*(noisefactor[0][i][1]+noisefactor[1][i][1]);//or should we use MIN??? + dctblock[1][0][i] *= 0.5*(noisefactor[0][i][1]+noisefactor[1][i][1]);//or should we use MIN??? + } + } + if (4*noisevar>(linehvar[2]+linehvar[3])) {//horizontal lines + for (int i=1; i<8; i++) { + dctblock[2][0][i] *= 0.5*(noisefactor[2][i][1]+noisefactor[3][i][1]);//or should we use MIN??? + dctblock[3][0][i] *= 0.5*(noisefactor[2][i][1]+noisefactor[3][i][1]);//or should we use MIN??? + } + } + + //vertical lines + if (4*noisevar>(linevvar[0]+linevvar[2])) {//vertical lines + for (int i=1; i<8; i++) { + dctblock[0][i][0] *= 0.5*(noisefactor[0][i][0]+noisefactor[2][i][0]);//or should we use MIN??? + dctblock[2][i][0] *= 0.5*(noisefactor[0][i][0]+noisefactor[2][i][0]);//or should we use MIN??? + } + } + if (4*noisevar>(linevvar[1]+linevvar[3])) {//vertical lines + for (int i=1; i<8; i++) { + dctblock[1][i][0] *= 0.5*(noisefactor[1][i][0]+noisefactor[3][i][0]);//or should we use MIN??? + dctblock[3][i][0] *= 0.5*(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 back to image matrix + 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; + } + if(plistener) plistener->setProgress(progress); + + //if(plistener) plistener->setProgress(fabs((float)top/height)); + } + // clean up + delete [] cfain; + delete [] cfablur; + delete [] cfadiff; + delete [] cfadn; + //free(buffer); + } + +} +#undef TS + + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +/* + Discrete Cosine Transform Code + + Copyright(C) 1997 Takuya OOURA (email: ooura@mmm.t.u-tokyo.ac.jp). + You may use, copy, modify this code for any purpose and + without fee. You may distribute this ORIGINAL package. + */ + + +/* + Short Discrete Cosine Transform + data length :8x8 + method :row-column, radix 4 FFT + functions + ddct8x8s : 8x8 DCT + function prototypes + void ddct8x8s(int isgn, float **a); + */ + + +/* + -------- 8x8 DCT (Discrete Cosine Transform) / Inverse of DCT -------- + [definition] + 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) +{ + 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/color.cc b/rtengine/color.cc new file mode 100644 index 000000000..b66654946 --- /dev/null +++ b/rtengine/color.cc @@ -0,0 +1,2567 @@ +/* +* This file is part of RawTherapee. +* +* Copyright (c) 2004-2010 Gabor Horvath +* +* RawTherapee is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* RawTherapee is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General 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 "color.h" +#include "iccmatrices.h" +#include "mytime.h" + +using namespace std; + +namespace rtengine { + + extern const Settings* settings; + + LUTf Color::cachef; + LUTf Color::gamma2curve = 0; + + LUTf Color::gammatab; + LUTf Color::igammatab_srgb; + LUTf Color::gammatab_srgb; + + // 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; //(MAXVAL* 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 / MAXVAL) )); + } + else { + cachef[i] = 327.68*((kappa*i/MAXVAL+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::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::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 fy = (0.00862069 * L) + 0.137932; // (L+16)/116 + float fx = (0.002 * a) + fy; + float fz = fy - (0.005 * b); + + x = 65535.0*f2xyz(fx)*D50x; + // y = 65535.0*f2xyz(fy); + z = 65535.0*f2xyz(fz)*D50z; + y=(L>epskap) ? 65535.0*fy*fy*fy : 65535.0*L/kappa; + + } + + void Color::XYZ2Lab(float X, float Y, float Z, float &L, float &a, float &b) { + + float X1 = X/D50x; + float Z1 = Z/D50z; + + float fx = (X1<65535.0 ? (cachef[std::max(X1,0.f)]) : (327.68*exp(log(X1/MAXVAL)/3.0 ))); + float fy = (Y<65535.0 ? (cachef[std::max(Y,0.f)]) : (327.68*exp(log(Y/MAXVAL)/3.0 ))); + float fz = (Z1<65535.0 ? (cachef[std::max(Z1,0.f)]) : (327.68*exp(log(Z1/MAXVAL)/3.0 ))); + + L = (116.0 * fy - 5242.88); //5242.88=16.0*327.68; + a = (500.0 * (fx - fy) ); + b = (200.0 * (fy - fz) ); + + } + + void Color::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>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/MAXVAL)/3.0 ))); + float fy = (Y<65535.0 ? cachef[Y] : (327.68*exp(log(Y/MAXVAL)/3.0 ))); + float fz = (Z<65535.0 ? cachef[Z] : (327.68*exp(log(Z/MAXVAL)/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::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 + do { + inGamut=true; + + //Lprov1=LL; + float aprov1=Chprov1*cos(HH); + float bprov1=Chprov1*sin(HH); + + //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 "highlight reconstruction" is enabled or the point is completely white (clipped, no color), don't control Gamut + if (!isHLEnabled && (R>ClipLevel || G>ClipLevel || B>ClipLevel)) { +#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; iL[i][j]/327.68f; + float CC=sqrt(SQR(lab->a[i][j]/327.68f) + SQR(lab->b[i][j]/327.68f)); + float HH=atan2(lab->b[i][j],lab->a[i][j]); + float Chprov1=CC; + float Lprov1=LL; + float Loldd, Coldd; + if(gamut) { + bool neg, more_rgb; + 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; + lab->a[i][j] = Chprov1*cos(HH+correctionHuechroma)*327.68f; + lab->b[i][j] = Chprov1*sin(HH+correctionHuechroma)*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..e3834a7cb --- /dev/null +++ b/rtengine/color.h @@ -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 . + */ + +#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 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; + // 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 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 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); + + // 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) ); + } + + // gamma functions on [0,65535] based on look-up tables + 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); + + //void gamutmap(LabImage* ); + static void gamutmap(float &X, float &Y, float &Z, const double p[3][3]); + + 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..b81c35bc3 --- /dev/null +++ b/rtengine/colorclip.h @@ -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 . + */ +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 + * + * 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; + + 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); + } + + 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..747aa107d --- /dev/null +++ b/rtengine/colortemp.cc @@ -0,0 +1,589 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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" + +namespace rtengine { + +extern const Settings* settings; + +ColorTemp::ColorTemp (double t, double g, Glib::ustring m) : temp(t), green(g), method(m) { + + clip (temp, green); +} + +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; +} + +ColorTemp::ColorTemp (double mulr, double mulg, double mulb) { + method = "Custom"; + mul2temp (mulr, mulg, mulb, temp, green); +} + +void ColorTemp::mul2temp (double rmul, double gmul, double bmul, 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, 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); +} + +/* + 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 +} + +void ColorTemp::spectrum_to_xyz(double (*spec_intens)(double wavelength, double m1, double m2, double temp), double _m1, double _m2, double _temp, 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.00645 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 +*/ + + static const double cie_colour_match[97][3] = {//350nm to 830nm + {0.0000000,0.000000,0.000000}, {0.0000000,0.000000,0.000000}, {0.0001299,0.000392,0.000606}, + {0.0002321,0.000007,0.001086}, {0.0004149,0.000012,0.001946}, {0.0007416,0.000022,0.003846}, + {0.001368,0.000039,0.006450}, {0.002236,0.000064,0.010550}, {0.004243,0.000120,0.020050}, + {0.007650,0.000217,0.036210}, {0.014310,0.000396,0.067850}, {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.039050}, {0.283900,0.011600,1.385600}, {0.328500,0.016840,1.622960}, + {0.348280,0.023000,1.747100}, {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.812950}, + {0.057950,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.078250}, {0.109600,0.793200,0.057250}, + {0.165500,0.862000,0.042160}, {0.225750,0.914850,0.029840}, {0.290400,0.954000,0.020300}, + {0.359700,0.980300,0.013400}, {0.433450,0.994950,0.008750}, {0.512050,1.000000,0.005750}, + {0.594500,0.995000,0.003900}, {0.678400,0.978600,0.002750}, {0.762100,0.952000,0.002100}, + {0.842500,0.915400,0.001800}, {0.916300,0.870000,0.001650}, {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.854450,0.381000,0.000190}, {0.751400,0.321000,0.000100}, {0.642400,0.265000,0.000050}, + {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.011359,0.004102,0.000000}, {0.008111,0.002929,0.000000}, + {0.005790,0.002091,0.000000}, {0.004109,0.001484,0.000000}, {0.002899,0.001047,0.000000}, + {0.002049,0.000740,0.000000}, {0.001440,0.000520,0.000000}, {0.001000,0.000361,0.000000}, + {0.000690,0.000249,0.000000}, {0.000476,0.000172,0.000000}, {0.000332,0.000120,0.000000}, + {0.000235,0.000085,0.000000}, {0.000166,0.000060,0.000000}, {0.000117,0.000042,0.000000}, + {0.000083,0.000030,0.000000}, {0.000059,0.000021,0.000000}, {0.000042,0.000015,0.000000}, + {0.000029,0.000011,0.000000}, {0.000021,0.000007,0.000000}, {0.000015,0.000005,0.000000}, + {0.000010,0.000004,0.000000}, {0.000007,0.000003,0.000000}, {0.000005,0.000002,0.000000}, + {0.000004,0.000001,0.000000}, {0.000003,0.000001,0.000000}, {0.000002,0.000001,0.000000}, + {0.000001,0.000001,0.000000} + }; + + for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) { + + double Me; + + Me = (*spec_intens)(lambda, _m1, _m2, _temp); + X += Me * cie_colour_match[i][0]; + Y += Me * cie_colour_match[i][1]; + Z += Me * cie_colour_match[i][2]; + } + XYZ = (X + Y + Z); + x = X / XYZ; + y = Y / XYZ; + z = Z / XYZ; +} + +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]); +} + +// spectral data for Daylight direct Sun: I have choose 5300K beacuse Nikon=5200K, Olympus=5300K, Panasonic=5500K, Leica=5400K, Minolta=5100K +double ColorTemp::Daylight5300_spect(double wavelength, double m1, double m2, double temp) +{ + static const double Su53[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}; + + int wlm = (int) ((wavelength -350.)/5.); + return (Su53[wlm]); +} + +//spectral data for Daylight Cloudy: I have choose 6200K beacuse Nikon=6000K, Olympus=6000K, Panasonic=6200K, Leica=6400K, Minolta=6500K +double ColorTemp::Cloudy6200_spect(double wavelength, double m1, double m2, double temp) +{ + static const double Clo62[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}; + + int wlm = (int) ((wavelength -350.)/5.); + return (Clo62[wlm]); +} + +//spectral data for Daylight Shade: I have choose 7600K beacuse Nikon=8000K, Olympus=7500K, Panasonic=7500K, Leica=7500K, Minolta=7500K +double ColorTemp::Shade7600_spect(double wavelength, double m1, double m2, double temp) +{ + static const double Sha76[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}; + + int wlm = (int) ((wavelength -350.)/5.); + return (Sha76[wlm]); +} + +//spectral data for tungsten - incandescent 2856K +double ColorTemp::A2856_spect(double wavelength, double m1, double m2, double temp) +{ + static const double A2856[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}; + + int wlm = (int) ((wavelength -350.)/5.); + return (A2856[wlm]); +} + +//spectral data for fluo F1 Daylight 6430K +double ColorTemp::FluoF1_spect(double wavelength, double m1, double m2, double temp) +{ + static const double fluoF1[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}; + + int wlm = (int) ((wavelength -350.)/5.); + return (fluoF1[wlm]); +} + +//spectral data for fluo F2 Cool white 4230K +double ColorTemp::FluoF2_spect(double wavelength, double m1, double m2, double temp) +{ + static const double fluoF2[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}; + + int wlm = (int) ((wavelength -350.)/5.); + return (fluoF2[wlm]); +} + +//spectral data for fluo F3 White 3450K +double ColorTemp::FluoF3_spect(double wavelength, double m1, double m2, double temp) +{ + static const double fluoF3[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}; + + int wlm = (int) ((wavelength -350.)/5.); + return (fluoF3[wlm]); +} + +//spectral data for fluo F4 Warm white 2940K +double ColorTemp::FluoF4_spect(double wavelength, double m1, double m2, double temp) +{ + static const double fluoF4[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}; + + int wlm = (int) ((wavelength -350.)/5.); + return (fluoF4[wlm]); +} + +//spectral data for fluo F5 Daylight 6350K +double ColorTemp::FluoF5_spect(double wavelength, double m1, double m2, double temp) +{ + static const double fluoF5[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}; + + int wlm = (int) ((wavelength -350.)/5.); + return (fluoF5[wlm]); +} + +//spectral data for fluo F6 Lite white 4150K +double ColorTemp::FluoF6_spect(double wavelength, double m1, double m2, double temp) +{ + static const double fluoF6[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}; + + int wlm = (int) ((wavelength -350.)/5.); + return (fluoF6[wlm]); +} + +//spectral data for fluo F7 D65 Daylight simulator 6500K +double ColorTemp::FluoF7_spect(double wavelength, double m1, double m2, double temp) +{ + static const double fluoF7[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}; + + int wlm = (int) ((wavelength -350.)/5.); + return (fluoF7[wlm]); +} + +//spectral data for fluo F8 D50 simulator Sylvania F40 Design 5000K +double ColorTemp::FluoF8_spect(double wavelength, double m1, double m2, double temp) +{ + static const double fluoF8[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}; + + int wlm = (int) ((wavelength -350.)/5.); + return (fluoF8[wlm]); +} + +//spectral data for fluo F9 Cool white deluxe 4150K +double ColorTemp::FluoF9_spect(double wavelength, double m1, double m2, double temp) +{ + static const double fluoF9[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}; + + int wlm = (int) ((wavelength -350.)/5.); + return (fluoF9[wlm]); +} + +//spectral data for fluo F10 Philips TL85 - 5000K +double ColorTemp::FluoF10_spect(double wavelength, double m1, double m2, double temp) +{ + static const double fluoF10[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}; + + int wlm = (int) ((wavelength -350.)/5.); + return (fluoF10[wlm]); +} + +//spectral data for fluo F11 Philips TL84 4150K +double ColorTemp::FluoF11_spect(double wavelength, double m1, double m2, double temp) +{ + static const double fluoF11[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}; + + int wlm = (int) ((wavelength -350.)/5.); + return (fluoF11[wlm]); +} + +//spectral data for fluo F12 Philips TL83 3000K +double ColorTemp::FluoF12_spect(double wavelength, double m1, double m2, double temp) +{ + static const double fluoF12[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}; + + int wlm = (int) ((wavelength -350.)/5.); + return (fluoF12[wlm]); +} + +//spectral data for HMI lamp studio "Osram" 4800K (for film, spectacle, studio...) +double ColorTemp::HMI_spect(double wavelength, double m1, double m2, double temp) +{ + static const double Hmi[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}; + + int wlm = (int) ((wavelength -350.)/5.); + return (Hmi[wlm]); +} + +//spectral data for GTI lamp : Graphiclite & ColorMatch for Photography 5000K +double ColorTemp::GTI_spect(double wavelength, double m1, double m2, double temp) +{ + static const double Gti[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}; + + int wlm = (int) ((wavelength -350.)/5.); + return (Gti[wlm]); +} + +//spectral data for JudgeIII Lamp D50 +double ColorTemp::JudgeIII_spect(double wavelength, double m1, double m2, double temp) +{ + static const double Jud[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}; + + int wlm = (int) ((wavelength -350.)/5.); + return (Jud[wlm]); +} + +//spectral data for Solux lamp : 3500K +double ColorTemp::Solux3500_spect(double wavelength, double m1, double m2, double temp) +{ + static const double Solux35[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}; + + int wlm = (int) ((wavelength -350.)/5.); + return (Solux35[wlm]); +} + +//spectral data for Solux lamp : 4100K +double ColorTemp::Solux4100_spect(double wavelength, double m1, double m2, double temp) +{ + static const double Solux41[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}; + + int wlm = (int) ((wavelength -350.)/5.); + return (Solux41[wlm]); +} + +//spectral data for Solux lamp : near Daylight (for example "muse d'Orsay..") - 4700K +double ColorTemp::Solux4700_spect(double wavelength, double m1, double m2, double temp) +{ + static const double Solux47[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}; + + int wlm = (int) ((wavelength -350.)/5.); + return (Solux47[wlm]); +} + +//spectral data for Solux lamp : near Daylight 4400K - test National Gallery +double ColorTemp::NG_Solux4700_spect(double wavelength, double m1, double m2, double temp) +{ + static const double NGSolux[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}; + + int wlm = (int) ((wavelength -350.)/5.); + return (NGSolux[wlm]); +} + +//spectral data for LED LSI Lumelex 2040 - test National Gallery +double ColorTemp::NG_LEDLSI2040_spect(double wavelength, double m1, double m2, double temp) +{ + static const double NGLsi[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}; + + int wlm = (int) ((wavelength -350.)/5.); + return (NGLsi[wlm]); +} +//spectral data for LED CRS SP12 WWMR16 - test National Gallery +double ColorTemp::NG_CRSSP12WWMR16_spect(double wavelength, double m1, double m2, double temp) +{ + static const double NGCRSSP12[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}; + + int wlm = (int) ((wavelength -350.)/5.); + return (NGCRSSP12[wlm]); +} + +//spectral data for Flash daylight 5500K (Leica...) +double ColorTemp::Flash5500_spect(double wavelength, double m1, double m2, double temp) +{ + static const double FL55[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}; + + int wlm = (int) ((wavelength -350.)/5.); + return (FL55[wlm]); +} + +//spectral data for Flash daylight 6000K (Canon, Pentax, Olympus,...Standard) +double ColorTemp::Flash6000_spect(double wavelength, double m1, double m2, double temp) +{ + static const double FL60[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}; + + int wlm = (int) ((wavelength -350.)/5.); + return (FL60[wlm]); +} + +//spectral data for Flash daylight 6500K (Nikon, Minolta, Panasonic, Sony...) +double ColorTemp::Flash6500_spect(double wavelength, double m1, double m2, double temp) +{ + static const double FL65[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}; + + int wlm = (int) ((wavelength -350.)/5.); + return (FL65[wlm]); +} + +void ColorTemp::temp2mul (double temp, double green, double& rmul, double& gmul, double& bmul) { + + clip (temp, green); + + double xD, yD, x_D, y_D, interm; + double x, y, z; + + // We first test for specially handled methods + if (method == "Daylight" ) spectrum_to_xyz(Daylight5300_spect, 0., 0., 0., x, y, z); + else if(method == "Cloudy" ) spectrum_to_xyz(Cloudy6200_spect, 0., 0., 0., x, y, z); + else if(method == "Shade" ) spectrum_to_xyz(Shade7600_spect, 0., 0., 0., x, y, z); + else if(method == "Tungsten" ) spectrum_to_xyz(A2856_spect, 0., 0., 0., x, y, z); + else if(method == "Fluo F1" ) spectrum_to_xyz(FluoF1_spect, 0., 0., 0., x, y, z); + else if(method == "Fluo F2" ) spectrum_to_xyz(FluoF2_spect, 0., 0., 0., x, y, z); + else if(method == "Fluo F3" ) spectrum_to_xyz(FluoF3_spect, 0., 0., 0., x, y, z); + else if(method == "Fluo F4" ) spectrum_to_xyz(FluoF4_spect, 0., 0., 0., x, y, z); + else if(method == "Fluo F5" ) spectrum_to_xyz(FluoF5_spect, 0., 0., 0., x, y, z); + else if(method == "Fluo F6" ) spectrum_to_xyz(FluoF6_spect, 0., 0., 0., x, y, z); + else if(method == "Fluo F7" ) spectrum_to_xyz(FluoF7_spect, 0., 0., 0., x, y, z); + else if(method == "Fluo F8" ) spectrum_to_xyz(FluoF8_spect, 0., 0., 0., x, y, z); + else if(method == "Fluo F9" ) spectrum_to_xyz(FluoF9_spect, 0., 0., 0., x, y, z); + else if(method == "Fluo F10" ) spectrum_to_xyz(FluoF10_spect, 0., 0., 0., x, y, z); + else if(method == "Fluo F11" ) spectrum_to_xyz(FluoF11_spect, 0., 0., 0., x, y, z); + else if(method == "Fluo F12" ) spectrum_to_xyz(FluoF12_spect, 0., 0., 0., x, y, z); + else if(method == "HMI Lamp" ) spectrum_to_xyz(HMI_spect, 0., 0., 0., x, y, z); + else if(method == "GTI Lamp" ) spectrum_to_xyz(GTI_spect, 0., 0., 0., x, y, z); + else if(method == "JudgeIII Lamp" ) spectrum_to_xyz(JudgeIII_spect, 0., 0., 0., x, y, z); + else if(method == "Solux Lamp 3500K" ) spectrum_to_xyz(Solux3500_spect, 0., 0., 0., x, y, z); + else if(method == "Solux Lamp 4100K" ) spectrum_to_xyz(Solux4100_spect, 0., 0., 0., x, y, z); + else if(method == "Solux Lamp 4700K" ) spectrum_to_xyz(Solux4700_spect, 0., 0., 0., x, y, z); + else if(method == "NG Solux Lamp 4700K" ) spectrum_to_xyz(NG_Solux4700_spect, 0., 0., 0., x, y, z); + else if(method == "LED LSI Lumelex 2040") spectrum_to_xyz(NG_LEDLSI2040_spect, 0., 0., 0., x, y, z); + else if(method == "LED CRS SP12 WWMR16" ) spectrum_to_xyz(NG_CRSSP12WWMR16_spect, 0., 0., 0., x, y, z); + else if(method == "Flash 5500K" ) spectrum_to_xyz(Flash5500_spect, 0., 0., 0., x, y, z); + else if(method == "Flash 6000K" ) spectrum_to_xyz(Flash6000_spect, 0., 0., 0., x, y, z); + else if(method == "Flash 6500K" ) spectrum_to_xyz(Flash6500_spect, 0., 0., 0., x, y, z); + 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_spect, 0., 0., temp, x, y, z); + } + else { + // from 4000K up to 25000K: using the D illuminant (daylight) which is standard + double m1, m2; + if (temp<=7000) + x_D = -4.6070e9/(temp*temp*temp) + 2.9678e6/(temp*temp) + 0.09911e3/temp + 0.244063; + else + x_D = -2.0064e9/(temp*temp*temp) + 1.9018e6/(temp*temp) + 0.24748e3/temp + 0.237040; + + 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_spect, m1, m2, 0., x, y, z); + xD=x;yD=y; + } + + } + + xD=x; yD=y; + + /* + 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); + } + */ + + double X = xD/yD; + double Y = 1.0; + double Z = (1.0-xD-yD)/yD; + + /*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]*X + sRGBd65_xyz[0][1]*Y + sRGBd65_xyz[0][2]*Z; + gmul = sRGBd65_xyz[1][0]*X + sRGBd65_xyz[1][1]*Y + sRGBd65_xyz[1][2]*Z; + bmul = sRGBd65_xyz[2][0]*X + sRGBd65_xyz[2][1]*Y + sRGBd65_xyz[2][2]*Z; + //}; + gmul /= green; + + double max = rmul; + if (gmul>max) max = gmul; + if (bmul>max) max = bmul; + rmul /= max; + gmul /= max; + bmul /= max; +} + +} diff --git a/rtengine/colortemp.h b/rtengine/colortemp.h new file mode 100644 index 000000000..8059c367f --- /dev/null +++ b/rtengine/colortemp.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 . + */ +#ifndef _COLORTEMP_ +#define _COLORTEMP_ + +#include +#include + +namespace rtengine { + +#define MINTEMP 2000 +#define MAXTEMP 25000 +#define MINGREEN 0.02 +#define MAXGREEN 5.0 +#define INITIALBLACKBODY 4000 + +class ColorTemp { + + private: + double temp; + double green; + Glib::ustring method; + + static void clip (double &temp, double &green); + + public: + + ColorTemp () : temp(-1), green(-1), method("Custom") {} + ColorTemp (double t, double g, Glib::ustring m); + ColorTemp (double mulr, double mulg, double mulb); + + inline double getTemp () { return temp; } + inline double getGreen () { return green; } + + void getMultipliers (double &mulr, double &mulg, double &mulb) { temp2mul (temp, green, mulr, mulg, mulb); } + + void mul2temp (double rmul, double gmul, double bmul, double& temp, double& green); + void temp2mul (double temp, double green, double& rmul, double& gmul, double& bmul); + //void temp2mul (double& rmul, double& gmul, double& bmul); + + 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 double Cloudy6200_spect (double wavelength, double m1, double m2, double temp); + static double Daylight5300_spect (double wavelength, double m1, double m2, double temp); + static double Shade7600_spect (double wavelength, double m1, double m2, double temp); + static double A2856_spect (double wavelength, double m1, double m2, double temp); + static double FluoF1_spect (double wavelength, double m1, double m2, double temp); + static double FluoF2_spect (double wavelength, double m1, double m2, double temp); + static double FluoF3_spect (double wavelength, double m1, double m2, double temp); + static double FluoF4_spect (double wavelength, double m1, double m2, double temp); + static double FluoF5_spect (double wavelength, double m1, double m2, double temp); + static double FluoF6_spect (double wavelength, double m1, double m2, double temp); + static double FluoF7_spect (double wavelength, double m1, double m2, double temp); + static double FluoF8_spect (double wavelength, double m1, double m2, double temp); + static double FluoF9_spect (double wavelength, double m1, double m2, double temp); + static double FluoF10_spect (double wavelength, double m1, double m2, double temp); + static double FluoF11_spect (double wavelength, double m1, double m2, double temp); + static double FluoF12_spect (double wavelength, double m1, double m2, double temp); + static double HMI_spect (double wavelength, double m1, double m2, double temp); + static double GTI_spect (double wavelength, double m1, double m2, double temp); + static double JudgeIII_spect (double wavelength, double m1, double m2, double temp); + static double Solux3500_spect (double wavelength, double m1, double m2, double temp); + static double Solux4100_spect (double wavelength, double m1, double m2, double temp); + static double Solux4700_spect (double wavelength, double m1, double m2, double temp); + static double NG_Solux4700_spect (double wavelength, double m1, double m2, double temp); + static double NG_LEDLSI2040_spect (double wavelength, double m1, double m2, double temp); + static double NG_CRSSP12WWMR16_spect (double wavelength, double m1, double m2, double temp); + static double Flash5500_spect (double wavelength, double m1, double m2, double temp); + static double Flash6000_spect (double wavelength, double m1, double m2, double temp); + static double Flash6500_spect (double wavelength, double m1, double m2, double temp); + + static void spectrum_to_xyz (double (*spec_intens)(double wavelength, double m1, double m2, double temp), double _m1, double _m2, double _temp, double &x, double &y, double &z); +}; +} +#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..0df25fa72 --- /dev/null +++ b/rtengine/cplx_wavelet_dec.h @@ -0,0 +1,454 @@ +/* + * 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 + + 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 = 8;//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..756b5ce8f --- /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 + * + * 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. + */ + +#include + + +#define FLOAT float +#define double_t double + +/******************************************************************************* + * FindCubicRoots + * + * 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 * 3.14159265) / 3) - a1 / 3; + x[2] = -2 * sqrtQ * cos((theta + 4 * 3.14159265) / 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); + } +} diff --git a/rtengine/cubint.cc b/rtengine/cubint.cc new file mode 100644 index 000000000..85f3d3ef6 --- /dev/null +++ b/rtengine/cubint.cc @@ -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 . + */ + +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); +} diff --git a/rtengine/cubintch.cc b/rtengine/cubintch.cc new file mode 100644 index 000000000..7bc55e089 --- /dev/null +++ b/rtengine/cubintch.cc @@ -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 . + */ + +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; 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 +#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 () { + x = 0; + y = 0; + ypp = 0; + 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::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, int skip) { + + //colormult = chroma_scale for Lab manipulations + + //----------------------------------------------------- + + bool needed; + DiagonalCurve* dCurve = NULL; +/* + // check if contrast curve is needed + needed = (saturation<-0.0001 || saturation>0.0001); + + // Filling the curve if needed + if (needed) { + + //%%%%%%%%%%%%%%%%% Saturation curve's control points %%%%%%%%%%%%%%%%% + std::vector satcurvePoints; + satcurvePoints.push_back((double)DCT_NURBS); + if (saturation>0) { + double satslope = (0.5+2*saturation/500.0)/(0.5-2*saturation/500.0); + double scale = (satlimthresh/100.1); + if (!satlimit) scale=100/100.1; + + satcurvePoints.push_back(0); //black point. Value in [0 ; 1] range + satcurvePoints.push_back(0); //black point. Value in [0 ; 1] range + + //if (satlimit) { + satcurvePoints.push_back(0.5-0.5*scale); //toe point + satcurvePoints.push_back(0.5-0.5*scale); //value at toe point + + satcurvePoints.push_back(0.5-(0.5/satslope)*scale); //toe point + satcurvePoints.push_back(0.5-0.5*scale); //value at toe point + + satcurvePoints.push_back(0.5+(0.5/satslope)*scale); //shoulder point + satcurvePoints.push_back(0.5+0.5*scale); //value at shoulder point + + satcurvePoints.push_back(0.5+0.5*scale); //shoulder point + satcurvePoints.push_back(0.5+0.5*scale); //value at shoulder point + / Commented out... + } else { + satcurvePoints.push_back(0.25+saturation/500.0); //toe point + satcurvePoints.push_back(0.25-saturation/500.0); //value at toe point + + satcurvePoints.push_back(0.75-saturation/500.0); //shoulder point + satcurvePoints.push_back(0.75+saturation/500.0); //value at shoulder point + } + / + + satcurvePoints.push_back(1); // white point + satcurvePoints.push_back(1); // value at white point + } else { + satcurvePoints.push_back(0); + satcurvePoints.push_back(-(saturation/200.0)); + + satcurvePoints.push_back(1); + satcurvePoints.push_back(1+saturation/200.0); + } + dCurve = new DiagonalCurve (satcurvePoints, CURVES_MIN_POLY_POINTS/skip); + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + fillCurveArray(dCurve, satCurve, skip, needed); + + delete dCurve; + dCurve = NULL; + } + else { + fillCurveArray(NULL, satCurve, skip, needed); + } +*/ + //----------------------------------------------------- + + 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 (dCurve && !dCurve->isIdentity()) + {needed = true;ccutili=true;} + } + 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 (dCurve && !dCurve->isIdentity()) + {needed = true;cclutili=true;} + } + 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_, + ToneCurveParams::eTCModeId curveMode, const std::vector& curvePoints, + 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 != ToneCurveParams::TC_MODE_STD) { + customToneCurve1.Set(tcurve); + delete tcurve; + tcurve = 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); + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + 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 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(i/(double)65535) * 65535; +} + +} diff --git a/rtengine/curves.h b/rtengine/curves.h new file mode 100644 index 000000000..44e9eb4ee --- /dev/null +++ b/rtengine/curves.h @@ -0,0 +1,424 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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 "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 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 = log(x); + return m2*x + (1.0-m2)*(2.0 - exp(k*lx))*exp(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_, ToneCurveParams::eTCModeId curveMode, const std::vector& curvePoints, 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 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& cclurvePoints, LUTf & aoutCurve, LUTf & boutCurve, LUTf & satCurve, LUTf & lhskCurve, 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 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; + 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; + 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 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 StandardToneCurve : 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 SatAndValueBlendingToneCurve : 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; +}; + + +// 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]; +} + +// 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 { + +#ifdef _DEBUG + assert (lutToneCurve); +#endif + 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 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; +} + +// 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 = LIM((r1*0.50f + r2*0.25f + r3*0.25f), 0.f, 65535.f); + g = LIM((g1*0.25f + g2*0.50f + g3*0.25f), 0.f, 65535.f); + b = LIM((b1*0.25f + b2*0.25f + b3*0.50f), 0.f, 65535.f); +} + +// 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); + } +} + +} + +#undef CLIPI + +#endif diff --git a/rtengine/dcp.cc b/rtengine/dcp.cc new file mode 100644 index 000000000..4a8be406b --- /dev/null +++ b/rtengine/dcp.cc @@ -0,0 +1,578 @@ +/* +* 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; + +DCPProfile::DCPProfile(Glib::ustring fname, bool isRTProfile) { + const int TIFFFloatSize=4; + const int TagColorMatrix1=50721, TagColorMatrix2=50722, TagProfileHueSatMapDims=50937; + 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=NULL; iHueDivisions=iSatDivisions=iValDivisions=iArrayCount=0; + + FILE *pFile = safe_g_fopen(fname, "rb"); + + TagDirectory *tagDir=ExifManager::parseTIFF(pFile, false); + + Tag* tag = tagDir->getTag(TagCalibrationIlluminant1); iLightSource1 = (tag!=NULL ? tag->toInt(0,SHORT) : -1); + tag = tagDir->getTag(TagCalibrationIlluminant2); iLightSource2 = (tag!=NULL ? tag->toInt(0,SHORT) : -1); + + bool hasSecondHueSat = tagDir->getTag(TagProfileHueSatMapData2)!=NULL; // some profiles have two matrices, but just one huesat + + // Color Matrix (1 is always there) + tag = tagDir->getTag(TagColorMatrix1); + + for (int row=0;row<3;row++) { + for (int col=0;col<3;col++) { + mColorMatrix1[col][row]=(float)tag->toDouble((col+row*3)*8); + } + } + ConvertDNGMatrix2XYZCAM(mColorMatrix1,mXYZCAM1); + + // LUT profile? Divisions counts + bool useSimpleLookup=false; + tag = tagDir->getTag(TagProfileHueSatMapDims); + if (tag==NULL) { + tag=tagDir->getTag(TagProfileLookTableDims); + useSimpleLookup=true; + } + + if (tag!=NULL) { + iHueDivisions=tag->toInt(0); iSatDivisions=tag->toInt(4); iValDivisions=tag->toInt(8); + + // Saturation maps. Need to be unwinded. + tag = tagDir->getTag(useSimpleLookup ? TagProfileLookTableData : TagProfileHueSatMapData1); + iArrayCount = tag->getCount()/3; + + aDeltas1=new HSBModify[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); + } + } + + // For second profile, copy everything from first profile is no better data is available + if (iLightSource2!=-1) { + // Second matrix + tag = tagDir->getTag(TagColorMatrix2); + + 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]); + } + } + + ConvertDNGMatrix2XYZCAM(mColorMatrix2,mXYZCAM2); + + // Second huesatmap, or copy of first + if (hasSecondHueSat) { + aDeltas2=new HSBModify[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); + } + } else { + if (aDeltas1!=NULL) { + aDeltas2=new HSBModify[iArrayCount]; + for (int i=0;igetTag(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 + for (int i=0;igetCount();i++) cPoints.push_back( tag->toDouble(i*TIFFFloatSize) ); + + // Create the curve + DiagonalCurve rawCurve(cPoints, CURVES_MIN_POLY_POINTS); + + toneCurve.Set((Curve*)&rawCurve); + } + + 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]) { + 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]; +} + + +const DCPProfile::HSBModify* DCPProfile::GetBestProfile(DCPLightType preferredProfile, double (*mXYZCAM)[3]) const { + bool use2=false; + + if (iLightSource2!=-1) { + DCPLightType t1=GetLightType(iLightSource1); DCPLightType t2=GetLightType(iLightSource2); + + // usually second is the daylight (default if nothing else found) + if (t2==Daylight) use2=true; + + switch (preferredProfile) { + case Tungsten: + if (t1==Tungsten) use2=false; else if (t2==Tungsten) use2=true; + break; + + case Fluorescent: + if (t1==Fluorescent) use2=false; else if (t2==Fluorescent) use2=true; + break; + + case Flash: + if (t1==Flash) use2=false; else if (t2==Flash) use2=true; + break; + + default: break; // e.g. Daylight + } + } + + // printf("DCP using LightSource %i: %i for requested %i\n", use2?2:1, use2?iLightSource2:iLightSource1, (int)preferredProfile); + + for (int row=0;row<3;row++) { + for (int col=0;col<3;col++) { + mXYZCAM[col][row]= (use2 ? mXYZCAM2[col][row] : mXYZCAM1[col][row]); + } + } + + return use2?aDeltas2:aDeltas1; +} + +DCPLightType DCPProfile::GetLightType(short iLightSource) const { + if (iLightSource==3 || iLightSource==17 || iLightSource==24) return Tungsten; + if (iLightSource==2 || (iLightSource>=12 && iLightSource<=15)) return Fluorescent; + if (iLightSource==4) return Flash; + return Daylight; +} + +void DCPProfile::Apply(Imagefloat *pImg, DCPLightType preferredProfile, Glib::ustring workingSpace, float rawWhiteFac, bool useToneCurve) const { + TMatrix mWork = iccStore->workingSpaceInverseMatrix (workingSpace); + + double mXYZCAM[3][3]; + const HSBModify* tableBase=GetBestProfile(preferredProfile,mXYZCAM); + + bool hasLUT=(iArrayCount>0); useToneCurve&=toneCurve; + + if (!hasLUT && !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]; + + // Preperations for LUT + float hScale = (iHueDivisions < 2) ? 0.0f : (iHueDivisions * (1.0f / 6.0f)); + float sScale = (float) (iSatDivisions - 1); + float vScale = (float) (iValDivisions - 1); + + int maxHueIndex0 = iHueDivisions - 1; + int maxSatIndex0 = iSatDivisions - 2; + int maxValIndex0 = iValDivisions - 2; + + int hueStep = iSatDivisions; + int valStep = iHueDivisions * hueStep; + + 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 (hasLUT && 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; + } + + // Apply the HueSatMap. Ported from Adobes reference implementation + float hueShift, satScale, valScale; + + if (iValDivisions < 2) // Optimize most common case of "2.5D" table. + { + float hScaled = hs * hScale; + float sScaled = ss * sScale; + + int hIndex0 = max((int)hScaled, 0); + int sIndex0 = max(min((int)sScaled,maxSatIndex0),0); + + int hIndex1 = hIndex0 + 1; + + if (hIndex0 >= maxHueIndex0) + { + hIndex0 = 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 * hueStep + + sIndex0; + + const HSBModify *entry01 = entry00 + (hIndex1 - hIndex0) * 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 * hScale; + float sScaled = ss * sScale; + float vScaled = vs * vScale; + + int hIndex0 = (int) hScaled; + int sIndex0 = max(min((int)sScaled,maxSatIndex0),0); + int vIndex0 = max(min((int)vScaled,maxValIndex0),0); + + int hIndex1 = hIndex0 + 1; + + if (hIndex0 >= maxHueIndex0) + { + hIndex0 = 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 * valStep + + hIndex0 * hueStep + + sIndex0; + + const HSBModify *entry01 = entry00 + (hIndex1 - hIndex0) * hueStep; + + const HSBModify *entry10 = entry00 + valStep; + const HSBModify *entry11 = entry01 + 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; + + // 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; + } + } + } +} + +// Integer variant is legacy, only used for thumbs. Simply take the matrix here +void DCPProfile::Apply(Image16 *pImg, DCPLightType preferredProfile, Glib::ustring workingSpace, bool useToneCurve) const { + TMatrix mWork = iccStore->workingSpaceInverseMatrix (workingSpace); + + double mXYZCAM[3][3]; + const HSBModify* tableBase=GetBestProfile(preferredProfile,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 Glib::Mutex smutex_; + Glib::Mutex::Lock lock(smutex_); + if ( instance_ == 0 ) + { + instance_ = new DCPStore(); + } + } + return instance_; +} + +// Reads all profiles from the given profiles dir +void DCPStore::init (Glib::ustring rtProfileDir) { + Glib::Mutex::Lock 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) { + Glib::Mutex::Lock 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")); +} \ No newline at end of file diff --git a/rtengine/dcp.h b/rtengine/dcp.h new file mode 100644 index 000000000..53208f3ff --- /dev/null +++ b/rtengine/dcp.h @@ -0,0 +1,89 @@ +/* +* 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 +#include +#include + +namespace rtengine { + enum DCPLightType { + Daylight=1, Tungsten=2, Fluorescent=3, Flash=4 + }; + + class DCPProfile { + struct HSBModify + { + float fHueShift; + float fSatScale; + float fValScale; + }; + + double mColorMatrix1[3][3],mColorMatrix2[3][3]; + double mXYZCAM1[3][3],mXYZCAM2[3][3]; // compatible to RTs xyz_cam + HSBModify *aDeltas1,*aDeltas2; + short iLightSource1,iLightSource2; + + int iHueDivisions, iSatDivisions, iValDivisions; + + int iHueStep, iValStep, iArrayCount; + + AdobeToneCurve toneCurve; + + void ConvertDNGMatrix2XYZCAM(const double (*mColorMatrix)[3], double (*mXYZCAM)[3]); + + const HSBModify* GetBestProfile(DCPLightType preferredProfile, double (*mXYZCAM)[3]) const; + + DCPLightType GetLightType(short iLightSource) const; + + public: + DCPProfile(Glib::ustring fname, bool isRTProfile); + ~DCPProfile(); + + void Apply(Imagefloat *pImg, DCPLightType preferredProfile, Glib::ustring workingSpace, float rawWhiteFac=1, bool useToneCurve=false) const; + void Apply(Image16 *pImg, DCPLightType preferredProfile, Glib::ustring workingSpace, bool useToneCurve) const; + }; + + class DCPStore { + Glib::Mutex 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..2624da976 --- /dev/null +++ b/rtengine/dcraw.c @@ -0,0 +1,9478 @@ +/* + dcraw.c -- Dave Coffin's raw photo decoder + Copyright 1997-2012 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.452 $ + $Date: 2012/07/23 04:28:00 $ + */ + +#define DCRAW_VERSION "9.16" + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#define _USE_MATH_DEFINES +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 + +#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 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; +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=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; +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]; +int mask[8][4], flip, tiff_flip, colors; +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 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 } }; + static const char filter2[6][6] = + { { 1,1,0,1,1,2 }, + { 1,1,2,1,1,0 }, + { 2,0,1,0,2,1 }, + { 1,1,2,1,1,0 }, + { 1,1,0,1,1,2 }, + { 0,2,1,2,0,1 } }; + + if (filters == 1) return filter[(row+top_margin)&15][(col+left_margin)&15]; + if (filters == 2) return filter2[(row+6) % 6][(col+6) % 6]; + return FC(row,col); +} + +#ifndef __GLIBC__ +char *my_memmem (char *haystack, size_t haystacklen, + char *needle, size_t needlelen) +{ + char *c; + for (c = haystack; c <= haystack + haystacklen - needlelen; c++) + if (!memcmp (c, needle, needlelen)) + return c; + return 0; +} +#define memmem my_memmem +#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; +} + +/* + getbits(-1) initializes the buffer + getbits(n) where 0 <= n <= 25 returns an n-bit integer + */ +unsigned CLASS getbithuff (int nbits, ushort *huff) +{ + static unsigned bitbuf=0; + static int vbits=0, reset=0; + unsigned c; + + if (nbits == -1) + 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; + 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 (row >= 0) 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)) 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) { + rp[0] -= 512; + goto next; + } else if (unique_id == 0x80000285) { +next: pix[0] = rp[0] + rp[2]; + pix[2] = rp[0] + rp[1]; + pix[1] = rp[0] + ((-778*rp[1] - (rp[2] << 11)) >> 12); + } else { + 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); + } + 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); +} + +/* + Figure out if a NEF file is compressed. These fancy heuristics + are only needed for the D100, thanks to a bug in some cameras + that tags all images as "compressed". + */ +int CLASS nikon_is_compressed() +{ + uchar test[256]; + int i; + + fseek (ifp, data_offset, SEEK_SET); + fread (test, 1, 256, ifp); + for (i=15; i < 256; i+=16) + if (test[i]) return 1; + return 0; +} + +/* + 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; + pred[c] += diff; + if (row >= 0 && (unsigned)(col+c) < width) + RAW(row,col+c) = pred[c]; + } + } + } + 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; + + 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, pwide, rbits, bite, half, irow, row, col, val, i; + UINT64 bitbuf=0; + + if (raw_width * 8 >= width * tiff_bps) /* Is raw_width in bytes? */ + pwide = (bwide = raw_width) * 8 / tiff_bps; + else bwide = (pwide = raw_width) * tiff_bps / 8; + rbits = bwide * 8 - pwide * 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 < pwide; 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)) = 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 / 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; +} + +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 (col < width) + if ((RAW(row,col) = pred[col & 1]) > 4098) 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; + + 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) + if (col < width) RAW(row,col) = curve[pix[i] << 1] >> 2; + col -= col & 1 ? 1:31; + } + } + free (data); +} + +#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[258], 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 ((width/4) * (height/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 sony_load_raw) { + mask[0][3] = 9; + goto sides; + } + if (load_raw == &CLASS canon_600_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=mask[m][0]; row < mask[m][2]; row++) + for (col=mask[m][1]; col < mask[m][3]; 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[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; + } 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) { + if (four_color_rgb && colors++) + mix_green = !half_size; + 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 == 2) 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 == 2) 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); + } +} + +/* + Adaptive Homogeneity-Directed interpolation is based on + the work of Keigo Hirakawa, Thomas Parks, and Paul Lee. + */ +#define TS 256 /* Tile Size */ + +void CLASS ahd_interpolate() +{ + int i, j, k, top, left, row, col, tr, tc, c, d, val, hm[2]; + ushort (*pix)[4], (*rix)[3]; + static const int dir[4] = { -1, 1, -TS, TS }; + unsigned ldiff[2][4], abdiff[2][4], leps, abeps; + float r, cbrt[0x10000], xyz[3], xyz_cam[3][4]; + ushort (*rgb)[TS][TS][3]; + short (*lab)[TS][TS][3], (*lix)[3]; + char (*homo)[TS][TS], *buffer; + + if (verbose) fprintf (stderr,_("AHD interpolation...\n")); + + 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]; + + border_interpolate(5); + buffer = (char *) malloc (26*TS*TS); /* 1664 kB */ + 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]; + xyz[0] = xyz[1] = xyz[2] = 0.5; + 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] = cbrt[CLIP((int) xyz[0])]; + xyz[1] = cbrt[CLIP((int) xyz[1])]; + xyz[2] = cbrt[CLIP((int) xyz[2])]; + lix[0][0] = 64 * (116 * xyz[1] - 16); + lix[0][1] = 64 * 500 * (xyz[0] - xyz[1]); + lix[0][2] = 64 * 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] = + (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) { + cam_mul[0] = getreal(type); + cam_mul[2] = 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 == 0x2010 && type != 7) + load_raw = &CLASS olympus_load_raw; + 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 == 1312 ? 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: filters = get2(); 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; + load_raw = &CLASS packed_load_raw; + load_flags = get4() && (filters=0x16161616) ? 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; 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 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]]; + 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 (!filters || !~filters) 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 (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; break; + } + 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: + load_raw = &CLASS nikon_load_raw; break; + case 34892: + load_raw = &CLASS lossy_dng_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: break; + default: is_raw = 0; + } + if (!dng_version) + if ( (tiff_samples == 3 && tiff_ifd[raw].bytes && + tiff_bps != 14 && tiff_bps != 2048 && tiff_compress != 32770) + || (tiff_bps == 8 && !strstr(make,"KODAK") && !strstr(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 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 > 100) 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); /* 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) { + fseek (ifp, 12, SEEK_CUR); + 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 == 0x2ff0) { + FORC4 cam_mul[c ^ 1] = get2(); + } else if (tag == 0xc000) { + c = order; + order = 0x4949; + width = get4(); + 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); + 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; + } + 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); + } + is_foveon = 1; +} + +/* + 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 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 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 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-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 X", 0, 0x3c4e, + { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } }, + { "Canon EOS-1D", 0, 0xe20, + { 6806,-179,-1020,-8097,16415,1687,-3267,4236,7690 } }, + { "Canon EOS", 0, 0, + { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } }, + { "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 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 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 SX1 IS", 0, 0, + { 6578,-259,-502,-5974,13030,3309,-308,1058,4970 } }, + { "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, 0, + { 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, + { 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 } }, + { "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 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 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 X-Pro1", 0, 0, + { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, + { "FUJIFILM X-S1", 0, 0, + { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, + { "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", 180, 0, + { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } }, + { "Kodak DCS560C", 188, 0, + { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } }, + { "Kodak DCS620C", 180, 0, + { 23617,-10175,-3149,-2054,11749,-272,2586,-489,3453 } }, + { "Kodak DCS620X", 185, 0, + { 13095,-6231,154,12221,-21,-2137,895,4602,2258 } }, + { "Kodak DCS660C", 214, 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, 0, + { 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 D50", 0, 0, + { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } }, + { "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 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 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 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 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, 0, + { 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, 0, + { 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-PM1", 0, 0, + { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } }, + { "OLYMPUS E-M5", 0, 0, + { 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-1", 0, 0, + { 10901,-4095,-1074,-1141,9208,2293,-62,1417,5158 } }, + { "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", 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-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-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-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-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-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 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 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, 0xffff, /* 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", 491, 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", 192, 0, /* DJC */ + { 7329,-2746,-405,-2691,9338,3354,-136,1259,5051 } }, + { "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-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-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-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 } }, + }; + 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() +{ + char head[32], *cp; + int hlen, flen, fsize, zero_fsize=1, i, c, is_canon; + struct jhead jh; + 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 struct { + int fsize; + char make[12], model[19], withjpeg; + } table[] = { + { 62464, "Kodak", "DC20" ,0 }, + { 124928, "Kodak", "DC20" ,0 }, + { 1652736, "Kodak", "DCS200" ,0 }, + { 4159302, "Kodak", "C330" ,0 }, + { 4162462, "Kodak", "C330" ,0 }, + { 460800, "Kodak", "C603v" ,0 }, + { 614400, "Kodak", "C603v" ,0 }, + { 6163328, "Kodak", "C603" ,0 }, + { 6166488, "Kodak", "C603" ,0 }, + { 9116448, "Kodak", "C603y" ,0 }, + { 311696, "ST Micro", "STV680 VGA" ,0 }, /* SPYz */ + { 787456, "Creative", "PC-CAM 600" ,0 }, + { 1138688, "Minolta", "RD175" ,0 }, + { 3840000, "Foculus", "531C" ,0 }, + { 307200, "Generic", "640x480" ,0 }, + { 786432, "AVT", "F-080C" ,0 }, + { 1447680, "AVT", "F-145C" ,0 }, + { 1920000, "AVT", "F-201C" ,0 }, + { 5067304, "AVT", "F-510C" ,0 }, + { 5067316, "AVT", "F-510C" ,0 }, + { 10134608, "AVT", "F-510C" ,0 }, + { 10134620, "AVT", "F-510C" ,0 }, + { 16157136, "AVT", "F-810C" ,0 }, + { 1409024, "Sony", "XCD-SX910CR" ,0 }, + { 2818048, "Sony", "XCD-SX910CR" ,0 }, + { 3884928, "Micron", "2010" ,0 }, + { 6624000, "Pixelink", "A782" ,0 }, + { 13248000, "Pixelink", "A782" ,0 }, + { 6291456, "RoverShot","3320AF" ,0 }, + { 6553440, "Canon", "PowerShot A460" ,0 }, + { 6653280, "Canon", "PowerShot A530" ,0 }, + { 6573120, "Canon", "PowerShot A610" ,0 }, + { 9219600, "Canon", "PowerShot A620" ,0 }, + { 9243240, "Canon", "PowerShot A470" ,0 }, + { 10341600, "Canon", "PowerShot A720 IS",0 }, + { 10383120, "Canon", "PowerShot A630" ,0 }, + { 12945240, "Canon", "PowerShot A640" ,0 }, + { 15636240, "Canon", "PowerShot A650" ,0 }, + { 5298000, "Canon", "PowerShot SD300" ,0 }, + { 7710960, "Canon", "PowerShot S3 IS" ,0 }, + { 15467760, "Canon", "PowerShot SX110 IS",0 }, + { 15534576, "Canon", "PowerShot SX120 IS",0 }, + { 18653760, "Canon", "PowerShot SX20 IS",0 }, + { 19131120, "Canon", "PowerShot SX220 HS",0 }, + { 21936096, "Canon", "PowerShot SX30 IS",0 }, + { 5939200, "OLYMPUS", "C770UZ" ,0 }, + { 1581060, "NIKON", "E900" ,1 }, /* or E900s,E910 */ + { 2465792, "NIKON", "E950" ,1 }, /* or E800,E700 */ + { 2940928, "NIKON", "E2100" ,1 }, /* or E2500 */ + { 4771840, "NIKON", "E990" ,1 }, /* or E995, Oly C3030Z */ + { 4775936, "NIKON", "E3700" ,1 }, /* or Optio 33WR */ + { 5869568, "NIKON", "E4300" ,1 }, /* or DiMAGE Z2 */ + { 5865472, "NIKON", "E4500" ,1 }, + { 7438336, "NIKON", "E5000" ,1 }, /* or E5700 */ + { 8998912, "NIKON", "COOLPIX S6" ,1 }, + { 1976352, "CASIO", "QV-2000UX" ,1 }, + { 3217760, "CASIO", "QV-3*00EX" ,1 }, + { 6218368, "CASIO", "QV-5700" ,1 }, + { 6054400, "CASIO", "QV-R41" ,1 }, + { 7530816, "CASIO", "QV-R51" ,1 }, + { 7684000, "CASIO", "QV-4000" ,1 }, + { 2937856, "CASIO", "EX-S20" ,1 }, + { 4948608, "CASIO", "EX-S100" ,1 }, + { 7542528, "CASIO", "EX-Z50" ,1 }, + { 7562048, "CASIO", "EX-Z500" ,1 }, + { 7753344, "CASIO", "EX-Z55" ,1 }, + { 7816704, "CASIO", "EX-Z60" ,1 }, + { 10843712, "CASIO", "EX-Z75" ,1 }, + { 10834368, "CASIO", "EX-Z750" ,1 }, + { 12310144, "CASIO", "EX-Z850" ,1 }, + { 12489984, "CASIO", "EX-Z8" ,1 }, + { 15499264, "CASIO", "EX-Z1050" ,1 }, + { 7426656, "CASIO", "EX-P505" ,1 }, + { 9313536, "CASIO", "EX-P600" ,1 }, + { 10979200, "CASIO", "EX-P700" ,1 }, + { 3178560, "PENTAX", "Optio S" ,1 }, + { 4841984, "PENTAX", "Optio S" ,1 }, + { 6114240, "PENTAX", "Optio S4" ,1 }, /* or S4i, CASIO EX-Z4 */ + { 10702848, "PENTAX", "Optio 750Z" ,1 }, + { 15980544, "AGFAPHOTO","DC-833m" ,1 }, + { 16098048, "SAMSUNG", "S85" ,1 }, + { 16215552, "SAMSUNG", "S85" ,1 }, + { 20487168, "SAMSUNG", "WB550" ,1 }, + { 24000000, "SAMSUNG", "WB550" ,1 }, + { 12582980, "Sinar", "" ,0 }, + { 33292868, "Sinar", "" ,0 }, + { 44390468, "Sinar", "" ,0 } }; + static const char *corp[] = + { "Canon", "NIKON", "EPSON", "KODAK", "Kodak", "OLYMPUS", "PENTAX", + "MINOLTA", "Minolta", "Konica", "CASIO", "Sinar", "Phase One", + "SAMSUNG", "Mamiya", "MOTOROLA", "LEICA" }; + + tiff_flip = flip = filters = -1; /* 0 is valid, so -1 is 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); + } 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+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); + if (table[i].withjpeg) + parse_external_jpeg(); + } + if (zero_fsize) fsize = 0; + if (make[0] == 0) parse_smal (0, flen); + if (make[0] == 0) parse_jpeg (is_raw = 0); + + for (i=0; i < sizeof corp / sizeof *corp; i++) + if (strstr (make, corp[i])) /* Simplify company names */ + strcpy (make, corp[i]); + if (!strncmp (make,"KODAK",5) && + ((cp = strstr(model," DIGITAL CAMERA")) || + (cp = strstr(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 && !strcmp(model,"K-5")) + { 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; + if (tiff_compress == 1) + load_raw = &CLASS packed_dng_load_raw; + if (tiff_compress == 7) + load_raw = &CLASS lossless_dng_load_raw; + goto dng_skip; + } + if ((is_canon = !strcmp(make,"Canon"))) + load_raw = memcmp (head+6,"HEAPCCDR",8) ? + &CLASS lossless_jpeg_load_raw : &CLASS canon_load_raw; + if (!strcmp(make,"NIKON")) { + if (!load_raw) + load_raw = &CLASS packed_load_raw; + if (model[0] == 'E') + load_flags |= !data_offset << 2 | 2; + } + if (!strcmp(make,"CASIO")) { + load_raw = &CLASS packed_load_raw; + maximum = 0xf7f; + } + +/* Set parameters based on camera name (for non-DNG files). */ + + if (is_foveon) { + if (height*2 < width) pixel_aspect = 0.5; + if (height > width) pixel_aspect = 2; + filters = 0; + simple_coeff(0); + } else if (is_canon && tiff_bps == 15) { + switch (width) { + case 3344: width -= 66; + case 3872: width -= 6; + } + filters = 0; + load_raw = &CLASS canon_sraw_load_raw; + } else if (!strcmp(model,"PowerShot 600")) { + height = 613; + width = 854; + raw_width = 896; + pixel_aspect = 607/628.0; + 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; + colors = 4; + filters = 0x1e4e1e4e; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A50")) { + height = 968; + width = 1290; + raw_width = 1320; + colors = 4; + filters = 0x1b4e4b1e; + goto canon_a5; + } else if (!strcmp(model,"PowerShot Pro70")) { + height = 1024; + width = 1552; + colors = 4; + filters = 0x1e4b4e1b; + goto canon_a5; + } else if (!strcmp(model,"PowerShot SD300")) { + height = 1752; + width = 2344; + raw_height = 1766; + raw_width = 2400; + top_margin = 12; + left_margin = 12; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A460")) { + height = 1960; + width = 2616; + raw_height = 1968; + raw_width = 2664; + top_margin = 4; + left_margin = 4; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A530")) { + height = 1984; + width = 2620; + raw_height = 1992; + raw_width = 2672; + top_margin = 6; + left_margin = 10; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A610")) { + if (canon_s2is()) strcpy (model+10, "S2 IS"); + height = 1960; + width = 2616; + raw_height = 1968; + raw_width = 2672; + top_margin = 8; + left_margin = 12; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A620")) { + height = 2328; + width = 3112; + raw_height = 2340; + raw_width = 3152; + top_margin = 12; + left_margin = 36; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A470")) { + height = 2328; + width = 3096; + raw_height = 2346; + raw_width = 3152; + top_margin = 6; + left_margin = 12; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A720 IS")) { + height = 2472; + width = 3298; + raw_height = 2480; + raw_width = 3336; + top_margin = 5; + left_margin = 6; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A630")) { + height = 2472; + width = 3288; + raw_height = 2484; + raw_width = 3344; + top_margin = 6; + left_margin = 12; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A640")) { + height = 2760; + width = 3672; + raw_height = 2772; + raw_width = 3736; + top_margin = 6; + left_margin = 12; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A650")) { + height = 3024; + width = 4032; + raw_height = 3048; + raw_width = 4104; + top_margin = 12; + left_margin = 48; + goto canon_a5; + } else if (!strcmp(model,"PowerShot S3 IS")) { + height = 2128; + width = 2840; + raw_height = 2136; + raw_width = 2888; + top_margin = 8; + left_margin = 44; +canon_a5: + tiff_bps = 10; + load_raw = &CLASS packed_load_raw; + load_flags = 40; + if (raw_width > 1600) zero_is_bad = 1; + } else if (!strcmp(model,"PowerShot SX110 IS")) { + height = 2760; + width = 3684; + raw_height = 2772; + raw_width = 3720; + top_margin = 12; + left_margin = 6; + load_raw = &CLASS packed_load_raw; + load_flags = 40; + zero_is_bad = 1; + } else if (!strcmp(model,"PowerShot SX120 IS")) { + height = 2742; + width = 3664; + raw_height = 2778; + raw_width = 3728; + top_margin = 18; + left_margin = 16; + filters = 0x49494949; + load_raw = &CLASS packed_load_raw; + load_flags = 40; + zero_is_bad = 1; + } else if (!strcmp(model,"PowerShot SX20 IS")) { + height = 3024; + width = 4032; + raw_height = 3048; + raw_width = 4080; + top_margin = 12; + left_margin = 24; + load_raw = &CLASS packed_load_raw; + load_flags = 40; + zero_is_bad = 1; + } else if (!strcmp(model,"PowerShot SX220 HS")) { + height = 3043; + width = 4072; + raw_height = 3060; + raw_width = 4168; + mask[0][0] = top_margin = 16; + mask[0][2] = top_margin + height; + mask[0][3] = left_margin = 92; + load_raw = &CLASS packed_load_raw; + load_flags = 8; + zero_is_bad = 1; + } else if (!strcmp(model,"PowerShot SX30 IS")) { + height = 3254; + width = 4366; + raw_height = 3276; + raw_width = 4464; + top_margin = 10; + left_margin = 25; + filters = 0x16161616; + load_raw = &CLASS packed_load_raw; + load_flags = 40; + zero_is_bad = 1; + } else if (!strcmp(model,"PowerShot Pro90 IS")) { + width = 1896; + colors = 4; + filters = 0xb4b4b4b4; + } else if (is_canon && raw_width == 2144) { + height = 1550; + width = 2088; + top_margin = 8; + left_margin = 4; + if (!strcmp(model,"PowerShot G1")) { + colors = 4; + filters = 0xb4b4b4b4; + } + } else if (is_canon && raw_width == 2224) { + height = 1448; + width = 2176; + top_margin = 6; + left_margin = 48; + } else if (is_canon && raw_width == 2376) { + height = 1720; + width = 2312; + top_margin = 6; + left_margin = 12; + } else if (is_canon && raw_width == 2672) { + height = 1960; + width = 2616; + top_margin = 6; + left_margin = 12; + } else if (is_canon && raw_width == 3152) { + height = 2056; + width = 3088; + top_margin = 12; + left_margin = 64; + if (unique_id == 0x80000170) + adobe_coeff ("Canon","EOS 300D"); + } else if (is_canon && raw_width == 3160) { + height = 2328; + width = 3112; + top_margin = 12; + left_margin = 44; + } else if (is_canon && raw_width == 3344) { + height = 2472; + width = 3288; + top_margin = 6; + left_margin = 4; + } else if (!strcmp(model,"EOS D2000C")) { + filters = 0x61616161; + black = curve[200]; + } else if (is_canon && raw_width == 3516) { + top_margin = 14; + left_margin = 42; + if (unique_id == 0x80000189) + adobe_coeff ("Canon","EOS 350D"); + goto canon_cr2; + } else if (is_canon && raw_width == 3596) { + top_margin = 12; + left_margin = 74; + goto canon_cr2; + } else if (is_canon && raw_width == 3744) { + height = 2760; + width = 3684; + top_margin = 16; + left_margin = 8; + if (unique_id > 0x2720000) { + top_margin = 12; + left_margin = 52; + } + } else if (is_canon && raw_width == 3944) { + height = 2602; + width = 3908; + top_margin = 18; + left_margin = 30; + } else if (is_canon && raw_width == 3948) { + top_margin = 18; + left_margin = 42; + height -= 2; + if (unique_id == 0x80000236) + adobe_coeff ("Canon","EOS 400D"); + if (unique_id == 0x80000254) + adobe_coeff ("Canon","EOS 1000D"); + goto canon_cr2; + } else if (is_canon && raw_width == 3984) { + top_margin = 20; + left_margin = 76; + height -= 2; + goto canon_cr2; + } else if (is_canon && raw_width == 4104) { + height = 3024; + width = 4032; + top_margin = 12; + left_margin = 48; + } else if (is_canon && raw_width == 4152) { + top_margin = 12; + left_margin = 192; + goto canon_cr2; + } else if (is_canon && raw_width == 4160) { + height = 3048; + width = 4048; + top_margin = 11; + left_margin = 104; + } else if (is_canon && raw_width == 4312) { + top_margin = 18; + left_margin = 22; + height -= 2; + if (unique_id == 0x80000176) + adobe_coeff ("Canon","EOS 450D"); + goto canon_cr2; + } else if (is_canon && raw_width == 4352) { + top_margin = 18; + left_margin = 62; + if (unique_id == 0x80000288) + adobe_coeff ("Canon","EOS 1100D"); + goto canon_cr2; + } else if (is_canon && raw_width == 4476) { + top_margin = 34; + left_margin = 90; + goto canon_cr2; + } else if (is_canon && raw_width == 4480) { + height = 3326; + width = 4432; + top_margin = 10; + left_margin = 12; + filters = 0x49494949; + } else if (is_canon && raw_width == 4496) { + height = 3316; + width = 4404; + top_margin = 50; + left_margin = 80; + } else if (is_canon && raw_width == 4832) { + top_margin = unique_id == 0x80000261 ? 51:26; + left_margin = 62; + if (unique_id == 0x80000252) + adobe_coeff ("Canon","EOS 500D"); + goto canon_cr2; + } else if (is_canon && raw_width == 5108) { + top_margin = 13; + left_margin = 98; + goto canon_cr2; + } else if (is_canon && raw_width == 5120) { + height -= top_margin = 45; + left_margin = 142; + width = 4916; + } else if (is_canon && raw_width == 5280) { + top_margin = 52; + left_margin = 72; + if (unique_id == 0x80000301) + adobe_coeff ("Canon","EOS 650D"); + goto canon_cr2; + } else if (is_canon && raw_width == 5344) { + top_margin = 51; + left_margin = 142; + if (unique_id == 0x80000269) { + top_margin = 100; + left_margin = 126; + height -= 2; + adobe_coeff ("Canon","EOS-1D X"); + } + if (unique_id == 0x80000270) + adobe_coeff ("Canon","EOS 550D"); + if (unique_id == 0x80000286) + adobe_coeff ("Canon","EOS 600D"); + goto canon_cr2; + } else if (is_canon && raw_width == 5360) { + top_margin = 51; + left_margin = 158; + goto canon_cr2; + } else if (is_canon && raw_width == 5712) { + height = 3752; + width = 5640; + top_margin = 20; + left_margin = 62; + } else if (is_canon && raw_width == 5792) { + top_margin = 51; + left_margin = 158; +canon_cr2: + height -= top_margin; + width -= left_margin; + } else if (is_canon && raw_width == 5920) { + height = 3870; + width = 5796; + top_margin = 80; + left_margin = 122; + } 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")) { + width -= 44; + } else if (!strcmp(model,"D3200") || + !strcmp(model,"D800")) { + 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 (tiff_compress == 34713 && !nikon_is_compressed()) { + load_raw = &CLASS packed_load_raw; + load_flags |= 1; + raw_width = (width += 3) + 3; + } + } else if (!strcmp(model,"D200")) { + left_margin = 1; + width -= 4; + filters = 0x94949494; + } else if (!strncmp(model,"D2H",3)) { + left_margin = 6; + width -= 14; + } else if (!strncmp(model,"D2X",3)) { + if (width == 3264) width -= 32; + else width -= 8; + } else if (!strncmp(model,"D300",4)) { + width -= 32; + } else if (!strncmp(model,"COOLPIX P",9)) { + 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) { + height = 963; + width = 1287; + raw_width = 1632; + maximum = 0x3f4; + colors = 4; + filters = 0x1e1e1e1e; + simple_coeff(3); + pre_mul[0] = 1.2085; + pre_mul[1] = 1.0943; + pre_mul[3] = 1.1103; + goto e900; + } else if (fsize == 2465792) { + height = 1203; + width = 1616; + raw_width = 2048; + colors = 4; + filters = 0x4b4b4b4b; + adobe_coeff ("NIKON","E950"); +e900: + tiff_bps = 10; + load_raw = &CLASS packed_load_raw; + load_flags = 6; + } else if (fsize == 4771840) { + height = 1540; + width = 2064; + colors = 4; + filters = 0xe1e1e1e1; + load_raw = &CLASS packed_load_raw; + load_flags = 6; + 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 (!strcmp(model,"E2100")) { + if (!timestamp && !nikon_e2100()) goto cp_e2500; + height = 1206; + width = 1616; + load_flags = 30; + } else if (!strcmp(model,"E2500")) { +cp_e2500: + strcpy (model, "E2500"); + height = 1204; + width = 1616; + colors = 4; + filters = 0x4b4b4b4b; + } else if (fsize == 4775936) { + height = 1542; + width = 2064; + load_raw = &CLASS packed_load_raw; + load_flags = 30; + 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) { + height = 1710; + width = 2288; + filters = 0x16161616; + if (!timestamp && minolta_z2()) { + strcpy (make, "Minolta"); + strcpy (model,"DiMAGE Z2"); + } + load_raw = &CLASS packed_load_raw; + load_flags = 6 + 24*(make[0] == 'M'); + } else if (!strcmp(model,"E4500")) { + height = 1708; + width = 2288; + colors = 4; + filters = 0xb4b4b4b4; + } else if (fsize == 7438336) { + height = 1924; + width = 2576; + colors = 4; + filters = 0xb4b4b4b4; + } else if (fsize == 8998912) { + height = 2118; + width = 2832; + maximum = 0xf83; + load_raw = &CLASS packed_load_raw; + load_flags = 30; + } 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 == 3328) { + width = 3262; + left_margin = 34; + } + if (!strcmp(model,"X10") || !strcmp(model,"X-S1")) + filters = 0x16161616; + if (!strcmp(model,"X-Pro1")) { + left_margin = 0; + filters = 2; + } + if (fuji_layout) raw_width *= is_raw; + } else if (!strcmp(model,"RD175")) { + height = 986; + width = 1534; + data_offset = 513; + filters = 0x61616161; + load_raw = &CLASS minolta_rd175_load_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")) { + load_raw = &CLASS unpacked_load_raw; + maximum = 0xfff; + 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(model,"Optio S")) { + if (fsize == 3178560) { + height = 1540; + width = 2064; + load_raw = &CLASS eight_bit_load_raw; + cam_mul[0] *= 4; + cam_mul[2] *= 4; + } else { + height = 1544; + width = 2068; + raw_width = 3136; + load_raw = &CLASS packed_load_raw; + maximum = 0xf7c; + } + } else if (fsize == 6114240) { + height = 1737; + width = 2324; + raw_width = 3520; + load_raw = &CLASS packed_load_raw; + maximum = 0xf7a; + } else if (!strcmp(model,"Optio 750Z")) { + height = 2302; + width = 3072; + load_raw = &CLASS packed_load_raw; + load_flags = 30; + } else if (!strcmp(model,"DC-833m")) { + height = 2448; + width = 3264; + order = 0x4949; + filters = 0x61616161; + load_raw = &CLASS unpacked_load_raw; + maximum = 0xfc00; + } else if (!strncmp(model,"S85",3)) { + height = 2448; + width = 3264; + raw_width = fsize/height/2; + order = 0x4d4d; + load_raw = &CLASS unpacked_load_raw; + } 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_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 (fsize == 20487168) { + height = 2808; + width = 3648; + goto wb550; + } else if (fsize == 24000000) { + height = 3000; + width = 4000; +wb550: + strcpy (model, "WB550"); + order = 0x4d4d; + load_raw = &CLASS unpacked_load_raw; + load_flags = 6; + maximum = 0x3df; + } else if (!strcmp(model,"STV680 VGA")) { + height = 484; + width = 644; + load_raw = &CLASS eight_bit_load_raw; + flip = 2; + filters = 0x16161616; + black = 16; + } else if (!strcmp(model,"N95")) { + height = raw_height - (top_margin = 2); + } else if (!strcmp(model,"531C")) { + height = 1200; + width = 1600; + load_raw = &CLASS unpacked_load_raw; + filters = 0x49494949; + } else if (!strcmp(model,"640x480")) { + height = 480; + width = 640; + load_raw = &CLASS eight_bit_load_raw; + gamma_curve (0.45, 4.5, 1, 255); + } else if (!strcmp(model,"F-080C")) { + height = 768; + width = 1024; + load_raw = &CLASS eight_bit_load_raw; + } else if (!strcmp(model,"F-145C")) { + height = 1040; + width = 1392; + load_raw = &CLASS eight_bit_load_raw; + } else if (!strcmp(model,"F-201C")) { + height = 1200; + width = 1600; + load_raw = &CLASS eight_bit_load_raw; + } else if (!strcmp(model,"F-510C")) { + height = 1958; + width = 2588; + load_raw = fsize < 7500000 ? + &CLASS eight_bit_load_raw : &CLASS unpacked_load_raw; + data_offset = fsize - width*height*(fsize >> 22); + maximum = 0xfff0; + } else if (!strcmp(model,"F-810C")) { + height = 2469; + width = 3272; + load_raw = &CLASS unpacked_load_raw; + maximum = 0xfff0; + } else if (!strcmp(model,"XCD-SX910CR")) { + height = 1024; + width = 1375; + raw_width = 1376; + filters = 0x49494949; + maximum = 0x3ff; + load_raw = fsize < 2000000 ? + &CLASS eight_bit_load_raw : &CLASS unpacked_load_raw; + } else if (!strcmp(model,"2010")) { + height = 1207; + width = 1608; + order = 0x4949; + filters = 0x16161616; + data_offset = 3212; + maximum = 0x3ff; + load_raw = &CLASS unpacked_load_raw; + } else if (!strcmp(model,"A782")) { + height = 3000; + width = 2208; + filters = 0x61616161; + load_raw = fsize < 10000000 ? + &CLASS eight_bit_load_raw : &CLASS unpacked_load_raw; + maximum = 0xffc0; + } else if (!strcmp(model,"3320AF")) { + height = 1536; + raw_width = width = 2048; + filters = 0x61616161; + load_raw = &CLASS unpacked_load_raw; + maximum = 0x3ff; + 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,"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 (!memcmp(head,"8BPS",4)) { + fseek (ifp, 14, SEEK_SET); + height = get4(); + width = get4(); + filters = 0x61616161; + data_offset = 68; + } + 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; + 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; + 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; + 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,"C603v")) { + height = 480; + width = 640; + if (fsize < 614400 || find_green (16, 16, 3840, 5120) < 25) goto c603v; + strcpy (model,"KAI-0340"); + height -= 3; + data_offset = 3840; + order = 0x4949; + load_raw = &CLASS unpacked_load_raw; + } else if (!strcmp(model,"C603y")) { + height = 2134; + width = 2848; +c603v: + filters = 0; + load_raw = &CLASS kodak_yrgb_load_raw; + gamma_curve (0, 3.875, 1, 255); + } else if (!strcmp(model,"C603")) { + raw_height = height = 2152; + raw_width = width = 2864; + goto c603; + } else if (!strcmp(model,"C330")) { + height = 1744; + width = 2336; + raw_height = 1779; + raw_width = 2338; + top_margin = 33; + left_margin = 1; +c603: + order = 0x4949; + if ((data_offset = fsize - raw_height*raw_width)) { + fseek (ifp, 168, SEEK_SET); + read_shorts (curve, 256); + } else gamma_curve (0, 3.875, 1, 255); + load_raw = &CLASS eight_bit_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 = 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); + } + data_offset += raw_width + 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; + height = 1024; + width = 1536; + data_offset = 79872; + load_raw = &CLASS eight_bit_load_raw; + 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; + } else if (!strcmp(model,"PC-CAM 600")) { + height = 768; + data_offset = width = 1024; + filters = 0x49494949; + load_raw = &CLASS eight_bit_load_raw; + } else if (!strcmp(model,"QV-2000UX")) { + height = 1208; + width = 1632; + data_offset = width * 2; + load_raw = &CLASS eight_bit_load_raw; + } else if (fsize == 3217760) { + height = 1546; + width = 2070; + raw_width = 2080; + load_raw = &CLASS eight_bit_load_raw; + } else if (!strcmp(model,"QV-4000")) { + height = 1700; + width = 2260; + load_raw = &CLASS unpacked_load_raw; + maximum = 0xffff; + } else if (!strcmp(model,"QV-5700")) { + height = 1924; + width = 2576; + raw_width = 3232; + tiff_bps = 10; + } else if (!strcmp(model,"QV-R41")) { + height = 1720; + width = 2312; + raw_width = 3520; + left_margin = 2; + } else if (!strcmp(model,"QV-R51")) { + height = 1926; + width = 2580; + raw_width = 3904; + } else if (!strcmp(model,"EX-S20")) { + height = 1208; + width = 1620; + raw_width = 2432; + flip = 3; + } else if (!strcmp(model,"EX-S100")) { + height = 1544; + width = 2058; + raw_width = 3136; + } else if (!strcmp(model,"EX-Z50")) { + height = 1931; + width = 2570; + raw_width = 3904; + } else if (!strcmp(model,"EX-Z500")) { + height = 1937; + width = 2577; + raw_width = 3904; + filters = 0x16161616; + } else if (!strcmp(model,"EX-Z55")) { + height = 1960; + width = 2570; + raw_width = 3904; + } else if (!strcmp(model,"EX-Z60")) { + height = 2145; + width = 2833; + raw_width = 3584; + filters = 0x16161616; + tiff_bps = 10; + } else if (!strcmp(model,"EX-Z75")) { + height = 2321; + width = 3089; + raw_width = 4672; + maximum = 0xfff; + } else if (!strcmp(model,"EX-Z750")) { + height = 2319; + width = 3087; + raw_width = 4672; + maximum = 0xfff; + } else if (!strcmp(model,"EX-Z850")) { + height = 2468; + width = 3279; + raw_width = 4928; + maximum = 0xfff; + } else if (!strcmp(model,"EX-Z8")) { + height = 2467; + width = 3281; + raw_height = 2502; + raw_width = 4992; + maximum = 0xfff; + } else if (fsize == 15499264) { /* EX-Z1050 or EX-Z1080 */ + height = 2752; + width = 3672; + raw_width = 5632; + } else if (!strcmp(model,"EX-P505")) { + height = 1928; + width = 2568; + raw_width = 3852; + maximum = 0xfff; + } else if (fsize == 9313536) { /* EX-P600 or QV-R61 */ + height = 2142; + width = 2844; + raw_width = 4288; + } else if (!strcmp(model,"EX-P700")) { + height = 2318; + width = 3082; + raw_width = 4672; + } + 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) 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 && colors == 3) + filters |= ((filters >> 2 & 0x22222222) | + (filters << 2 & 0x88888888)) & filters << 1; +notraw: + if (flip == -1) flip = tiff_flip; + if (flip == -1) 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 (wide*high, 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; /* "-h" implies "-f" */ + 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))); + if (document_mode == 3) { + top_margin = left_margin = fuji_width = 0; + height = raw_height; + if (width <= raw_width * 8 / tiff_bps) + width = raw_width * 8 / tiff_bps; + else width = raw_width; + } + iheight = (height + shrink) >> shrink; + iwidth = (width + shrink) >> shrink; + if (identify_only) { + if (verbose) { + 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; + } + image = (ushort (*)[4]) calloc (iheight*iwidth, sizeof *image); + merror (image, "main()"); + 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()"); + } + 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 (raw_image) { + 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 || filters < 1000) + vng_interpolate(); + else if (quality == 2) + ppg_interpolate(); + 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..a6379a4a5 --- /dev/null +++ b/rtengine/dcraw.cc @@ -0,0 +1,8349 @@ +/*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-2012 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.452 $ + $Date: 2012/07/23 04:28:00 $ + */ + +#define DCRAW_VERSION "9.16" + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#define _USE_MATH_DEFINES +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 + +#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 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 } }; + static const char filter2[6][6] = + { { 1,1,0,1,1,2 }, + { 1,1,2,1,1,0 }, + { 2,0,1,0,2,1 }, + { 1,1,2,1,1,0 }, + { 1,1,0,1,1,2 }, + { 0,2,1,2,0,1 } }; + + if (filters == 1) return filter[(row+top_margin)&15][(col+left_margin)&15]; + if (filters == 2) return filter2[(row+6) % 6][(col+6) % 6]; + return FC(row,col); +} + +#ifndef __GLIBC__ +char *my_memmem (char *haystack, size_t haystacklen, + char *needle, size_t needlelen) +{ + char *c; + for (c = haystack; c <= haystack + haystacklen - needlelen; c++) + if (!memcmp (c, needle, needlelen)) + return c; + return 0; +} +#define memmem my_memmem +#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; +} + +/* + getbits(-1) initializes the buffer + getbits(n) where 0 <= n <= 25 returns an n-bit integer + */ +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 == -1) + 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; + 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 (row >= 0) 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)) 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) { + rp[0] -= 512; + goto next; + } else if (unique_id == 0x80000285) { +next: pix[0] = rp[0] + rp[2]; + pix[2] = rp[0] + rp[1]; + pix[1] = rp[0] + ((-778*rp[1] - (rp[2] << 11)) >> 12); + } else { + 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); + } + 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); +} + +/* + Figure out if a NEF file is compressed. These fancy heuristics + are only needed for the D100, thanks to a bug in some cameras + that tags all images as "compressed". + */ +int CLASS nikon_is_compressed() +{ + uchar test[256]; + int i; + + fseek (ifp, data_offset, SEEK_SET); + fread (test, 1, 256, ifp); + for (i=15; i < 256; i+=16) + if (test[i]) return 1; + return 0; +} + +/* + 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; + pred[c] += diff; + if (row >= 0 && (unsigned)(col+c) < width) + RAW(row,col+c) = pred[c]; + } + } + } + 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; + + 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, pwide, rbits, bite, half, irow, row, col, val, i; + UINT64 bitbuf=0; + + if (raw_width * 8 >= width * tiff_bps) /* Is raw_width in bytes? */ + pwide = (bwide = raw_width) * 8 / tiff_bps; + else bwide = (pwide = raw_width) * tiff_bps / 8; + rbits = bwide * 8 - pwide * 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 < pwide; 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)) = 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 / 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; +} + +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 (col < width) + if ((RAW(row,col) = pred[col & 1]) > 4098) 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; + + 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]; +} + +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) + if (col < width) RAW(row,col) = curve[pix[i] << 1] >> 2; + col -= col & 1 ? 1:31; + } + } + free (data); +} + +#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[258], 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 ((width/4) * (height/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 sony_load_raw) { + mask[0][3] = 9; + goto sides; + } + if (load_raw == &CLASS canon_600_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=mask[m][0]; row < mask[m][2]; row++) + for (col=mask[m][1]; col < mask[m][3]; 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[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; + } 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) { + if (four_color_rgb && colors++) + mix_green = !half_size; + 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 function */ +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) { + cam_mul[0] = getreal(type); + cam_mul[2] = 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 == 0x2010 && type != 7) + load_raw = &CLASS olympus_load_raw; + 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 == 1312 ? 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); + } +} + +/*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: filters = get2(); 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; + load_raw = &CLASS packed_load_raw; + load_flags = get4() && (filters=0x16161616) ? 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; 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 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]]; + 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 (!filters || !~filters) 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 (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; break; + } + 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: + load_raw = &CLASS nikon_load_raw; break; + case 34892: + load_raw = &CLASS lossy_dng_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: break; + default: is_raw = 0; + } + if (!dng_version) + if ( (tiff_samples == 3 && tiff_ifd[raw].bytes && + tiff_bps != 14 && tiff_bps != 2048 && tiff_compress != 32770) + || (tiff_bps == 8 && !strstr(make,"KODAK") && !strstr(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 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 > 100) 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); /* 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) { + fseek (ifp, 12, SEEK_CUR); + 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 == 0x2ff0) { + FORC4 cam_mul[c ^ 1] = get2(); + } else if (tag == 0xc000) { + c = order; + order = 0x4949; + width = get4(); + 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); +/*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; + } + 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); + } + is_foveon = 1; +} + +/* + 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, 0x3a98, /* RT */ + { 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, /* RT */ + { 6319,-793,-614,-5809,13342,2738,-1132,1559,7971 } }, + { "Canon EOS 7D", 0, 0x3510, /* RT - Colin Walker */ + { 5962,-171,-732,-4189,12307,2099,-911,1981,6304 } }, + { "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, /* RT */ + { 7590,-1646,-673,-4697,12411,2568,-627,1118,7295 } }, + { "Canon EOS 30D", 0, 0, + { 6257,-303,-1000,-7880,15621,2396,-1714,1904,7046 } }, + { "Canon EOS 40D", 0, 0x3f60, /* RT */ + { 6070,-531,-883,-5763,13647,2315,-1533,2582,6801 } }, + { "Canon EOS 50D", 0, 0x3d93, + { 4920,616,-593,-6493,13964,2784,-1774,3178,7005 } }, + { "Canon EOS 60D", 0, 0x2ff7, /* RT - Colin Walker */ + { 5678,-179,-718,-4389,12381,2243,-869,1819,6380 } }, + { "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, /* RT */ + { 6246,-1272,-523,-5075,12357,3075,-1035,1825,7333 } }, + { "Canon EOS 500D", 0, 0x3479, + { 4763,712,-646,-6821,14399,2640,-1921,3276,6561 } }, + { "Canon EOS 550D", 0, 0x3dd7, /* RT - Lebedev*/ + { 6519,-772,-703,-4994,12737,2519,-1387,2492,6175 } }, + { "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 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-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, /* RT */ + { 7406,-1592,-646,-4856,12457,2698,-432,726,7921 } }, + { "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 X", 0, 0x3c4e, + { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } }, + { "Canon EOS-1D", 0, 0xe20, + { 6806,-179,-1020,-8097,16415,1687,-3267,4236,7690 } }, + { "Canon EOS", 0, 0, + { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } }, + { "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, /* RT */ + { 12535,-5030,-796,-2711,10134,3006,-413,1605,5264 } }, + { "Canon PowerShot G11", 0, 0, + { 12177,-4817,-1069,-1612,9864,2049,-98,850,4471 } }, + { "Canon PowerShot G12", 0, 0, /* RT */ + { 12222,-4097,-1380,-2876,11016,2130,-888,1630,4434 } }, + { "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 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 SX1 IS", 0, 0, + { 6578,-259,-502,-5974,13030,3309,-308,1058,4970 } }, + { "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, 0, + { 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, + { 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 } }, + { "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 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 X100", 0, 0, /* RT - Colin Walker */ + { 10841,-3288,-807,-4652,12552,2344,-642,1355,7206 } }, + { "FUJIFILM X10", 0, 0, + { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, + { "FUJIFILM X-Pro1", 0, 0, + { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, + { "FUJIFILM X-S1", 0, 0, + { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, + { "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", 180, 0, + { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } }, + { "Kodak DCS560C", 188, 0, + { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } }, + { "Kodak DCS620C", 180, 0, + { 23617,-10175,-3149,-2054,11749,-272,2586,-489,3453 } }, + { "Kodak DCS620X", 185, 0, + { 13095,-6231,154,12221,-21,-2137,895,4602,2258 } }, + { "Kodak DCS660C", 214, 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, /* RT */ + { 8498,-2633,-295,-5423,12869,2860,-777,1077,8124 } }, + { "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, /* RT */ + { 9211,-2521,-104,-6487,14280,2394,-754,1122,8033 } }, + { "NIKON D3100", 0, 0, /* RT */ + { 7729,-2212,-481,-5709,13148,2858,-1295,1908,8936 } }, + { "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, /* RT */ + { 8792,-2663,-344,-5221,12764,2752,-1491,2165,8121 } }, + { "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 D50", 0, 0, + { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } }, + { "NIKON D60", 0, 0, + { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } }, + { "NIKON D7000", 0, 0, /* RT - Tanveer(tsk1979) */ + { 7530,-1942,-255,-4318,11390,3362,-926,1694,7649 } }, + { "NIKON D700", 0, 0, /* RT */ + { 8364,-2503,-352,-6307,14026,2492,-1134,1512,8156 } }, + { "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 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 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 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, /* RT - Colin Walker */ + { 8510,-2355,-693,-4819,12520,2578,-1029,2067,7752 } }, + { "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, 0, /* RT - Colin Walker */ + { 9732,-2629,-999,-4899,12931,2173,-1243,2353,7457 } }, + { "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, /* RT - Colin Walker */ + { 8834,-2344,-804,-4691,12503,2448,-978,1919,7603 } }, + { "OLYMPUS E-P2", 0, 0xffd, /* RT - Colin Walker */ + { 7758,-1619,-800,-5002,12886,2349,-985,1964,8305 } }, + { "OLYMPUS E-P3", 0, 0, /* RT - Colin Walker */ + { 7041,-1794,-336,-3790,11192,2984,-1364,2625,6217 } }, + { "OLYMPUS E-PL1s", 0, 0, /* RT - Colin Walker */ + { 9010,-2271,-838,-4792,12753,2263,-1059,2058,7589 } }, + { "OLYMPUS E-PL1", 0, 0, /* RT - Colin Walker */ + { 9010,-2271,-838,-4792,12753,2263,-1059,2058,7589 } }, + { "OLYMPUS E-PL2", 0, 0, /* RT - Colin Walker */ + { 11975,-3351,-1184,-4500,12639,2061,-1230,2353,7009 } }, + { "OLYMPUS E-PL3", 0, 0, /* RT - Colin Walker */ + { 7041,-1794,-336,-3790,11192,2984,-1364,2625,6217 } }, + { "OLYMPUS E-PM1", 0, 0, + { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } }, + { "OLYMPUS E-M5", 0, 0, + { 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-1", 0, 0, /* RT - Colin Walker */ + { 8665,-2247,-762,-2424,10372,2382,-1011,2286,5189 } }, + { "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, /* RT */ + { 10962,-4428,-542,-5486,13023,2748,-569,842,8390 } }, + { "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", 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 } }, + { "Leica Camera AG M9 Digital Camera", 0, 0, /* RT */ + { 7181,-1706,-55,-3557,11409,2450,-621,2072,7533 } }, + { "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, /* RT */ + { 10435,-3208,-72,-2293,10506,2067,-486,1725,4682 } }, + { "LEICA V-LUX 3", 143, 0xfff, + { 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } }, + { "Panasonic DMC-FX150", 15, 0xfff, + { 9082,-2907,-925,-6119,13377,3058,-1797,2641,5609 } }, + { "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-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-GF5", 143, 0xfff, + { 8228,-2945,-660,-3938,11792,2430,-1094,2278,5793 } }, + { "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 } }, + { "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 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 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, 0xffff, /* 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", 491, 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", 192, 0, /* DJC */ + { 7329,-2746,-405,-2691,9338,3354,-136,1259,5051 } }, + { "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, /* RT */ + { 6509,-1333,-137,-6171,13621,2824,-1490,2226,6952 } }, + { "SONY DSLR-A850", 128, 0, + { 5413,-1162,-365,-5665,13098,2866,-608,1179,8440 } }, + { "SONY DSLR-A900", 128, 0, /* RT */ + { 5715,-1433,-410,-5603,12937,2989,-644,1247,8372 } }, + { "SONY NEX-5N", 138, 0, /* RT - Colin Walker */ + { 5130,-1055,-269,-4473,11797,3050,-701,1310,7121 } }, + { "SONY NEX-C3", 128, 0, /* RT - Colin Walker */ + { 5130,-1055,-269,-4473,11797,3050,-701,1310,7121 } }, + { "SONY NEX-3", 128, 0, /* RT - Colin Walker */ + { 5145,-741,-123,-4915,12310,2945,-794,1489,6906 } }, + { "SONY NEX-5", 128, 0, /* RT - Colin Walker */ + { 5154,-716,-115,-5065,12506,2882,-988,1715,6800 } }, + { "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-A65", 128, 0, + { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } }, + { "SONY SLT-A77", 128, 0, /* RT - Colin Walker */ + { 5126,-830,-261,-4788,12196,2934,-948,1602,7068 } } + }; + 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() +{ + char head[32], *cp; + int hlen, flen, fsize, zero_fsize=1, i, c, is_canon; + struct jhead jh; + 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 struct { + int fsize; + char make[12], model[19], withjpeg; + } table[] = { + { 62464, "Kodak", "DC20" ,0 }, + { 124928, "Kodak", "DC20" ,0 }, + { 1652736, "Kodak", "DCS200" ,0 }, + { 4159302, "Kodak", "C330" ,0 }, + { 4162462, "Kodak", "C330" ,0 }, + { 460800, "Kodak", "C603v" ,0 }, + { 614400, "Kodak", "C603v" ,0 }, + { 6163328, "Kodak", "C603" ,0 }, + { 6166488, "Kodak", "C603" ,0 }, + { 9116448, "Kodak", "C603y" ,0 }, + { 311696, "ST Micro", "STV680 VGA" ,0 }, /* SPYz */ + { 787456, "Creative", "PC-CAM 600" ,0 }, + { 1138688, "Minolta", "RD175" ,0 }, + { 3840000, "Foculus", "531C" ,0 }, + { 307200, "Generic", "640x480" ,0 }, + { 786432, "AVT", "F-080C" ,0 }, + { 1447680, "AVT", "F-145C" ,0 }, + { 1920000, "AVT", "F-201C" ,0 }, + { 5067304, "AVT", "F-510C" ,0 }, + { 5067316, "AVT", "F-510C" ,0 }, + { 10134608, "AVT", "F-510C" ,0 }, + { 10134620, "AVT", "F-510C" ,0 }, + { 16157136, "AVT", "F-810C" ,0 }, + { 1409024, "Sony", "XCD-SX910CR" ,0 }, + { 2818048, "Sony", "XCD-SX910CR" ,0 }, + { 3884928, "Micron", "2010" ,0 }, + { 6624000, "Pixelink", "A782" ,0 }, + { 13248000, "Pixelink", "A782" ,0 }, + { 6291456, "RoverShot","3320AF" ,0 }, + { 6553440, "Canon", "PowerShot A460" ,0 }, + { 6653280, "Canon", "PowerShot A530" ,0 }, + { 6573120, "Canon", "PowerShot A610" ,0 }, + { 9219600, "Canon", "PowerShot A620" ,0 }, + { 9243240, "Canon", "PowerShot A470" ,0 }, + { 10341600, "Canon", "PowerShot A720 IS",0 }, + { 10383120, "Canon", "PowerShot A630" ,0 }, + { 12945240, "Canon", "PowerShot A640" ,0 }, + { 15636240, "Canon", "PowerShot A650" ,0 }, + { 5298000, "Canon", "PowerShot SD300" ,0 }, + { 7710960, "Canon", "PowerShot S3 IS" ,0 }, + { 15467760, "Canon", "PowerShot SX110 IS",0 }, + { 15534576, "Canon", "PowerShot SX120 IS",0 }, + { 18653760, "Canon", "PowerShot SX20 IS",0 }, + { 19131120, "Canon", "PowerShot SX220 HS",0 }, + { 21936096, "Canon", "PowerShot SX30 IS",0 }, + { 5939200, "OLYMPUS", "C770UZ" ,0 }, + { 1581060, "NIKON", "E900" ,1 }, /* or E900s,E910 */ + { 2465792, "NIKON", "E950" ,1 }, /* or E800,E700 */ + { 2940928, "NIKON", "E2100" ,1 }, /* or E2500 */ + { 4771840, "NIKON", "E990" ,1 }, /* or E995, Oly C3030Z */ + { 4775936, "NIKON", "E3700" ,1 }, /* or Optio 33WR */ + { 5869568, "NIKON", "E4300" ,1 }, /* or DiMAGE Z2 */ + { 5865472, "NIKON", "E4500" ,1 }, + { 7438336, "NIKON", "E5000" ,1 }, /* or E5700 */ + { 8998912, "NIKON", "COOLPIX S6" ,1 }, + { 1976352, "CASIO", "QV-2000UX" ,1 }, + { 3217760, "CASIO", "QV-3*00EX" ,1 }, + { 6218368, "CASIO", "QV-5700" ,1 }, + { 6054400, "CASIO", "QV-R41" ,1 }, + { 7530816, "CASIO", "QV-R51" ,1 }, + { 7684000, "CASIO", "QV-4000" ,1 }, + { 2937856, "CASIO", "EX-S20" ,1 }, + { 4948608, "CASIO", "EX-S100" ,1 }, + { 7542528, "CASIO", "EX-Z50" ,1 }, + { 7562048, "CASIO", "EX-Z500" ,1 }, + { 7753344, "CASIO", "EX-Z55" ,1 }, + { 7816704, "CASIO", "EX-Z60" ,1 }, + { 10843712, "CASIO", "EX-Z75" ,1 }, + { 10834368, "CASIO", "EX-Z750" ,1 }, + { 12310144, "CASIO", "EX-Z850" ,1 }, + { 12489984, "CASIO", "EX-Z8" ,1 }, + { 15499264, "CASIO", "EX-Z1050" ,1 }, + { 7426656, "CASIO", "EX-P505" ,1 }, + { 9313536, "CASIO", "EX-P600" ,1 }, + { 10979200, "CASIO", "EX-P700" ,1 }, + { 3178560, "PENTAX", "Optio S" ,1 }, + { 4841984, "PENTAX", "Optio S" ,1 }, + { 6114240, "PENTAX", "Optio S4" ,1 }, /* or S4i, CASIO EX-Z4 */ + { 10702848, "PENTAX", "Optio 750Z" ,1 }, + { 15980544, "AGFAPHOTO","DC-833m" ,1 }, + { 16098048, "SAMSUNG", "S85" ,1 }, + { 16215552, "SAMSUNG", "S85" ,1 }, + { 20487168, "SAMSUNG", "WB550" ,1 }, + { 24000000, "SAMSUNG", "WB550" ,1 }, + { 12582980, "Sinar", "" ,0 }, + { 33292868, "Sinar", "" ,0 }, + { 44390468, "Sinar", "" ,0 } }; + static const char *corp[] = + { "Canon", "NIKON", "EPSON", "KODAK", "Kodak", "OLYMPUS", "PENTAX", + "MINOLTA", "Minolta", "Konica", "CASIO", "Sinar", "Phase One", + "SAMSUNG", "Mamiya", "MOTOROLA", "LEICA" }; + + tiff_flip = flip = filters = -1; /* 0 is valid, so -1 is 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); + } 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+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); + if (table[i].withjpeg) + parse_external_jpeg(); + } + if (zero_fsize) fsize = 0; + if (make[0] == 0) parse_smal (0, flen); + if (make[0] == 0) parse_jpeg (is_raw = 0); + + for (i=0; i < sizeof corp / sizeof *corp; i++) + if (strstr (make, corp[i])) /* Simplify company names */ + strcpy (make, corp[i]); + if (!strncmp (make,"KODAK",5) && + ((cp = strstr(model," DIGITAL CAMERA")) || + (cp = strstr(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 && !strcmp(model,"K-5")) + { 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; + if (tiff_compress == 1) + load_raw = &CLASS packed_dng_load_raw; + if (tiff_compress == 7) + load_raw = &CLASS lossless_dng_load_raw; + goto dng_skip; + } + if ((is_canon = !strcmp(make,"Canon"))) + load_raw = memcmp (head+6,"HEAPCCDR",8) ? + &CLASS lossless_jpeg_load_raw : &CLASS canon_load_raw; + if (!strcmp(make,"NIKON")) { + if (!load_raw) + load_raw = &CLASS packed_load_raw; + if (model[0] == 'E') + load_flags |= !data_offset << 2 | 2; + } + if (!strcmp(make,"CASIO")) { + load_raw = &CLASS packed_load_raw; + maximum = 0xf7f; + } + +/* Set parameters based on camera name (for non-DNG files). */ + + if (is_foveon) { + if (height*2 < width) pixel_aspect = 0.5; + if (height > width) pixel_aspect = 2; + filters = 0; + simple_coeff(0); + } else if (is_canon && tiff_bps == 15) { + switch (width) { + case 3344: width -= 66; + case 3872: width -= 6; + } + filters = 0; + load_raw = &CLASS canon_sraw_load_raw; + } else if (!strcmp(model,"PowerShot 600")) { + height = 613; + width = 854; + raw_width = 896; + pixel_aspect = 607/628.0; + 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; + colors = 4; + filters = 0x1e4e1e4e; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A50")) { + height = 968; + width = 1290; + raw_width = 1320; + colors = 4; + filters = 0x1b4e4b1e; + goto canon_a5; + } else if (!strcmp(model,"PowerShot Pro70")) { + height = 1024; + width = 1552; + colors = 4; + filters = 0x1e4b4e1b; + goto canon_a5; + } else if (!strcmp(model,"PowerShot SD300")) { + height = 1752; + width = 2344; + raw_height = 1766; + raw_width = 2400; + top_margin = 12; + left_margin = 12; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A460")) { + height = 1960; + width = 2616; + raw_height = 1968; + raw_width = 2664; + top_margin = 4; + left_margin = 4; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A530")) { + height = 1984; + width = 2620; + raw_height = 1992; + raw_width = 2672; + top_margin = 6; + left_margin = 10; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A610")) { + if (canon_s2is()) strcpy (model+10, "S2 IS"); + height = 1960; + width = 2616; + raw_height = 1968; + raw_width = 2672; + top_margin = 8; + left_margin = 12; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A620")) { + height = 2328; + width = 3112; + raw_height = 2340; + raw_width = 3152; + top_margin = 12; + left_margin = 36; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A470")) { + height = 2328; + width = 3096; + raw_height = 2346; + raw_width = 3152; + top_margin = 6; + left_margin = 12; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A720 IS")) { + height = 2472; + width = 3298; + raw_height = 2480; + raw_width = 3336; + top_margin = 5; + left_margin = 6; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A630")) { + height = 2472; + width = 3288; + raw_height = 2484; + raw_width = 3344; + top_margin = 6; + left_margin = 12; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A640")) { + height = 2760; + width = 3672; + raw_height = 2772; + raw_width = 3736; + top_margin = 6; + left_margin = 12; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A650")) { + height = 3024; + width = 4032; + raw_height = 3048; + raw_width = 4104; + top_margin = 12; + left_margin = 48; + goto canon_a5; + } else if (!strcmp(model,"PowerShot S3 IS")) { + height = 2128; + width = 2840; + raw_height = 2136; + raw_width = 2888; + top_margin = 8; + left_margin = 44; +canon_a5: + tiff_bps = 10; + load_raw = &CLASS packed_load_raw; + load_flags = 40; + if (raw_width > 1600) zero_is_bad = 1; + } else if (!strcmp(model,"PowerShot SX110 IS")) { + height = 2760; + width = 3684; + raw_height = 2772; + raw_width = 3720; + top_margin = 12; + left_margin = 6; + load_raw = &CLASS packed_load_raw; + load_flags = 40; + zero_is_bad = 1; + } else if (!strcmp(model,"PowerShot SX120 IS")) { + height = 2742; + width = 3664; + raw_height = 2778; + raw_width = 3728; + top_margin = 18; + left_margin = 16; + filters = 0x49494949; + load_raw = &CLASS packed_load_raw; + load_flags = 40; + zero_is_bad = 1; + } else if (!strcmp(model,"PowerShot SX20 IS")) { + height = 3024; + width = 4032; + raw_height = 3048; + raw_width = 4080; + top_margin = 12; + left_margin = 24; + load_raw = &CLASS packed_load_raw; + load_flags = 40; + zero_is_bad = 1; + } else if (!strcmp(model,"PowerShot SX220 HS")) { + height = 3043; + width = 4072; + raw_height = 3060; + raw_width = 4168; + mask[0][0] = top_margin = 16; + mask[0][2] = top_margin + height; + mask[0][3] = left_margin = 92; + load_raw = &CLASS packed_load_raw; + load_flags = 8; + zero_is_bad = 1; + } else if (!strcmp(model,"PowerShot SX30 IS")) { + height = 3254; + width = 4366; + raw_height = 3276; + raw_width = 4464; + top_margin = 10; + left_margin = 25; + filters = 0x16161616; + load_raw = &CLASS packed_load_raw; + load_flags = 40; + zero_is_bad = 1; + } else if (!strcmp(model,"PowerShot Pro90 IS")) { + width = 1896; + colors = 4; + filters = 0xb4b4b4b4; + } else if (is_canon && raw_width == 2144) { + height = 1550; + width = 2088; + top_margin = 8; + left_margin = 4; + if (!strcmp(model,"PowerShot G1")) { + colors = 4; + filters = 0xb4b4b4b4; + } + } else if (is_canon && raw_width == 2224) { + height = 1448; + width = 2176; + top_margin = 6; + left_margin = 48; + } else if (is_canon && raw_width == 2376) { + height = 1720; + width = 2312; + top_margin = 6; + left_margin = 12; + } else if (is_canon && raw_width == 2672) { + height = 1960; + width = 2616; + top_margin = 6; + left_margin = 12; + } else if (is_canon && raw_width == 3152) { + height = 2056; + width = 3088; + top_margin = 12; + left_margin = 64; + if (unique_id == 0x80000170) + adobe_coeff ("Canon","EOS 300D"); + } else if (is_canon && raw_width == 3160) { + height = 2328; + width = 3112; + top_margin = 12; + left_margin = 44; + } else if (is_canon && raw_width == 3344) { + height = 2472; + width = 3288; + top_margin = 6; + left_margin = 4; + } else if (!strcmp(model,"EOS D2000C")) { + filters = 0x61616161; + black = curve[200]; + } else if (is_canon && raw_width == 3516) { + top_margin = 14; + left_margin = 42; + if (unique_id == 0x80000189) + adobe_coeff ("Canon","EOS 350D"); + goto canon_cr2; + } else if (is_canon && raw_width == 3596) { + top_margin = 12; + left_margin = 74; + goto canon_cr2; + } else if (is_canon && raw_width == 3744) { + height = 2760; + width = 3684; + top_margin = 16; + left_margin = 8; + if (unique_id > 0x2720000) { + top_margin = 12; + left_margin = 52; + } + } else if (is_canon && raw_width == 3944) { + height = 2602; + width = 3908; + top_margin = 18; + left_margin = 30; + } else if (is_canon && raw_width == 3948) { + top_margin = 18; + left_margin = 42; + height -= 2; + if (unique_id == 0x80000236) + adobe_coeff ("Canon","EOS 400D"); + if (unique_id == 0x80000254) + adobe_coeff ("Canon","EOS 1000D"); + goto canon_cr2; + } else if (is_canon && raw_width == 3984) { + top_margin = 20; + left_margin = 76; + height -= 2; + goto canon_cr2; + } else if (is_canon && raw_width == 4104) { + height = 3024; + width = 4032; + top_margin = 12; + left_margin = 48; + } else if (is_canon && raw_width == 4152) { + top_margin = 12; + left_margin = 192; + goto canon_cr2; + } else if (is_canon && raw_width == 4160) { + height = 3048; + width = 4048; + top_margin = 11; + left_margin = 104; + } else if (is_canon && raw_width == 4312) { + top_margin = 18; + left_margin = 22; + height -= 2; + if (unique_id == 0x80000176) + adobe_coeff ("Canon","EOS 450D"); + goto canon_cr2; + } else if (is_canon && raw_width == 4352) { + top_margin = 18; + left_margin = 62; + if (unique_id == 0x80000288) + adobe_coeff ("Canon","EOS 1100D"); + goto canon_cr2; + } else if (is_canon && raw_width == 4476) { + top_margin = 34; + left_margin = 90; + goto canon_cr2; + } else if (is_canon && raw_width == 4480) { + height = 3326; + width = 4432; + top_margin = 10; + left_margin = 12; + filters = 0x49494949; + } else if (is_canon && raw_width == 4496) { + height = 3316; + width = 4404; + top_margin = 50; + left_margin = 80; + } else if (is_canon && raw_width == 4832) { + top_margin = unique_id == 0x80000261 ? 51:26; + left_margin = 62; + if (unique_id == 0x80000252) + adobe_coeff ("Canon","EOS 500D"); + goto canon_cr2; + } else if (is_canon && raw_width == 5108) { + top_margin = 13; + left_margin = 98; + goto canon_cr2; + } else if (is_canon && raw_width == 5120) { + height -= top_margin = 45; + left_margin = 142; + width = 4916; + } else if (is_canon && raw_width == 5280) { + top_margin = 52; + left_margin = 72; + if (unique_id == 0x80000301) + adobe_coeff ("Canon","EOS 650D"); + goto canon_cr2; + } else if (is_canon && raw_width == 5344) { + top_margin = 51; + left_margin = 142; + if (unique_id == 0x80000269) { + top_margin = 100; + left_margin = 126; + height -= 2; + adobe_coeff ("Canon","EOS-1D X"); + } + if (unique_id == 0x80000270) + adobe_coeff ("Canon","EOS 550D"); + if (unique_id == 0x80000286) + adobe_coeff ("Canon","EOS 600D"); + goto canon_cr2; + } else if (is_canon && raw_width == 5360) { + top_margin = 51; + left_margin = 158; + goto canon_cr2; + } else if (is_canon && raw_width == 5712) { + height = 3752; + width = 5640; + top_margin = 20; + left_margin = 62; + } else if (is_canon && raw_width == 5792) { + top_margin = 51; + left_margin = 158; +canon_cr2: + height -= top_margin; + width -= left_margin; + } else if (is_canon && raw_width == 5920) { + height = 3870; + width = 5796; + top_margin = 80; + left_margin = 122; + } 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")) { + width -= 44; + } else if (!strcmp(model,"D3200") || + !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 (tiff_compress == 34713 && !nikon_is_compressed()) { + load_raw = &CLASS packed_load_raw; + load_flags |= 1; + raw_width = (width += 3) + 3; + } + } else if (!strcmp(model,"D200")) { + left_margin = 1; + width -= 4; + filters = 0x94949494; + } else if (!strncmp(model,"D2H",3)) { + left_margin = 6; + width -= 14; + } else if (!strncmp(model,"D2X",3)) { + if (width == 3264) width -= 32; + else width -= 8; + } else if (!strncmp(model,"D300",4)) { + width -= 32; + } else if (!strncmp(model,"COOLPIX P",9)) { + 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) { + height = 963; + width = 1287; + raw_width = 1632; + maximum = 0x3f4; + colors = 4; + filters = 0x1e1e1e1e; + simple_coeff(3); + pre_mul[0] = 1.2085; + pre_mul[1] = 1.0943; + pre_mul[3] = 1.1103; + goto e900; + } else if (fsize == 2465792) { + height = 1203; + width = 1616; + raw_width = 2048; + colors = 4; + filters = 0x4b4b4b4b; + adobe_coeff ("NIKON","E950"); +e900: + tiff_bps = 10; + load_raw = &CLASS packed_load_raw; + load_flags = 6; + } else if (fsize == 4771840) { + height = 1540; + width = 2064; + colors = 4; + filters = 0xe1e1e1e1; + load_raw = &CLASS packed_load_raw; + load_flags = 6; + 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 (!strcmp(model,"E2100")) { + if (!timestamp && !nikon_e2100()) goto cp_e2500; + height = 1206; + width = 1616; + load_flags = 30; + } else if (!strcmp(model,"E2500")) { +cp_e2500: + strcpy (model, "E2500"); + height = 1204; + width = 1616; + colors = 4; + filters = 0x4b4b4b4b; + } else if (fsize == 4775936) { + height = 1542; + width = 2064; + load_raw = &CLASS packed_load_raw; + load_flags = 30; + 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) { + height = 1710; + width = 2288; + filters = 0x16161616; + if (!timestamp && minolta_z2()) { + strcpy (make, "Minolta"); + strcpy (model,"DiMAGE Z2"); + } + load_raw = &CLASS packed_load_raw; + load_flags = 6 + 24*(make[0] == 'M'); + } else if (!strcmp(model,"E4500")) { + height = 1708; + width = 2288; + colors = 4; + filters = 0xb4b4b4b4; + } else if (fsize == 7438336) { + height = 1924; + width = 2576; + colors = 4; + filters = 0xb4b4b4b4; + } else if (fsize == 8998912) { + height = 2118; + width = 2832; + maximum = 0xf83; + load_raw = &CLASS packed_load_raw; + load_flags = 30; + } 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 == 3328) { + width = 3262; + left_margin = 34; + } + if (!strcmp(model,"X10") || !strcmp(model,"X-S1")) + filters = 0x16161616; + if (!strcmp(model,"X-Pro1")) { + left_margin = 0; + filters = 2; + } + if (fuji_layout) raw_width *= is_raw; + } else if (!strcmp(model,"RD175")) { + height = 986; + width = 1534; + data_offset = 513; + filters = 0x61616161; + load_raw = &CLASS minolta_rd175_load_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")) { + load_raw = &CLASS unpacked_load_raw; + maximum = 0xfff; + 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(model,"Optio S")) { + if (fsize == 3178560) { + height = 1540; + width = 2064; + load_raw = &CLASS eight_bit_load_raw; + cam_mul[0] *= 4; + cam_mul[2] *= 4; + } else { + height = 1544; + width = 2068; + raw_width = 3136; + load_raw = &CLASS packed_load_raw; + maximum = 0xf7c; + } + } else if (fsize == 6114240) { + height = 1737; + width = 2324; + raw_width = 3520; + load_raw = &CLASS packed_load_raw; + maximum = 0xf7a; + } else if (!strcmp(model,"Optio 750Z")) { + height = 2302; + width = 3072; + load_raw = &CLASS packed_load_raw; + load_flags = 30; + } else if (!strcmp(model,"DC-833m")) { + height = 2448; + width = 3264; + order = 0x4949; + filters = 0x61616161; + load_raw = &CLASS unpacked_load_raw; + maximum = 0xfc00; + } else if (!strncmp(model,"S85",3)) { + height = 2448; + width = 3264; + raw_width = fsize/height/2; + order = 0x4d4d; + load_raw = &CLASS unpacked_load_raw; + } 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_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 (fsize == 20487168) { + height = 2808; + width = 3648; + goto wb550; + } else if (fsize == 24000000) { + height = 3000; + width = 4000; +wb550: + strcpy (model, "WB550"); + order = 0x4d4d; + load_raw = &CLASS unpacked_load_raw; + load_flags = 6; + maximum = 0x3df; + } else if (!strcmp(model,"STV680 VGA")) { + height = 484; + width = 644; + load_raw = &CLASS eight_bit_load_raw; + flip = 2; + filters = 0x16161616; + black = 16; + } else if (!strcmp(model,"N95")) { + height = raw_height - (top_margin = 2); + } else if (!strcmp(model,"531C")) { + height = 1200; + width = 1600; + load_raw = &CLASS unpacked_load_raw; + filters = 0x49494949; + } else if (!strcmp(model,"640x480")) { + height = 480; + width = 640; + load_raw = &CLASS eight_bit_load_raw; + gamma_curve (0.45, 4.5, 1, 255); + } else if (!strcmp(model,"F-080C")) { + height = 768; + width = 1024; + load_raw = &CLASS eight_bit_load_raw; + } else if (!strcmp(model,"F-145C")) { + height = 1040; + width = 1392; + load_raw = &CLASS eight_bit_load_raw; + } else if (!strcmp(model,"F-201C")) { + height = 1200; + width = 1600; + load_raw = &CLASS eight_bit_load_raw; + } else if (!strcmp(model,"F-510C")) { + height = 1958; + width = 2588; + load_raw = fsize < 7500000 ? + &CLASS eight_bit_load_raw : &CLASS unpacked_load_raw; + data_offset = fsize - width*height*(fsize >> 22); + maximum = 0xfff0; + } else if (!strcmp(model,"F-810C")) { + height = 2469; + width = 3272; + load_raw = &CLASS unpacked_load_raw; + maximum = 0xfff0; + } else if (!strcmp(model,"XCD-SX910CR")) { + height = 1024; + width = 1375; + raw_width = 1376; + filters = 0x49494949; + maximum = 0x3ff; + load_raw = fsize < 2000000 ? + &CLASS eight_bit_load_raw : &CLASS unpacked_load_raw; + } else if (!strcmp(model,"2010")) { + height = 1207; + width = 1608; + order = 0x4949; + filters = 0x16161616; + data_offset = 3212; + maximum = 0x3ff; + load_raw = &CLASS unpacked_load_raw; + } else if (!strcmp(model,"A782")) { + height = 3000; + width = 2208; + filters = 0x61616161; + load_raw = fsize < 10000000 ? + &CLASS eight_bit_load_raw : &CLASS unpacked_load_raw; + maximum = 0xffc0; + } else if (!strcmp(model,"3320AF")) { + height = 1536; + raw_width = width = 2048; + filters = 0x61616161; + load_raw = &CLASS unpacked_load_raw; + maximum = 0x3ff; + 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,"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 (!memcmp(head,"8BPS",4)) { + fseek (ifp, 14, SEEK_SET); + height = get4(); + width = get4(); + filters = 0x61616161; + data_offset = 68; + } + 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; + 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; + 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; + 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,"C603v")) { + height = 480; + width = 640; + if (fsize < 614400 || find_green (16, 16, 3840, 5120) < 25) goto c603v; + strcpy (model,"KAI-0340"); + height -= 3; + data_offset = 3840; + order = 0x4949; + load_raw = &CLASS unpacked_load_raw; + } else if (!strcmp(model,"C603y")) { + height = 2134; + width = 2848; +c603v: + filters = 0; + load_raw = &CLASS kodak_yrgb_load_raw; + gamma_curve (0, 3.875, 1, 255); + } else if (!strcmp(model,"C603")) { + raw_height = height = 2152; + raw_width = width = 2864; + goto c603; + } else if (!strcmp(model,"C330")) { + height = 1744; + width = 2336; + raw_height = 1779; + raw_width = 2338; + top_margin = 33; + left_margin = 1; +c603: + order = 0x4949; + if ((data_offset = fsize - raw_height*raw_width)) { + fseek (ifp, 168, SEEK_SET); + read_shorts (curve, 256); + } else gamma_curve (0, 3.875, 1, 255); + load_raw = &CLASS eight_bit_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 = 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); + } + data_offset += raw_width + 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; + height = 1024; + width = 1536; + data_offset = 79872; + load_raw = &CLASS eight_bit_load_raw; + 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; + } else if (!strcmp(model,"PC-CAM 600")) { + height = 768; + data_offset = width = 1024; + filters = 0x49494949; + load_raw = &CLASS eight_bit_load_raw; + } else if (!strcmp(model,"QV-2000UX")) { + height = 1208; + width = 1632; + data_offset = width * 2; + load_raw = &CLASS eight_bit_load_raw; + } else if (fsize == 3217760) { + height = 1546; + width = 2070; + raw_width = 2080; + load_raw = &CLASS eight_bit_load_raw; + } else if (!strcmp(model,"QV-4000")) { + height = 1700; + width = 2260; + load_raw = &CLASS unpacked_load_raw; + maximum = 0xffff; + } else if (!strcmp(model,"QV-5700")) { + height = 1924; + width = 2576; + raw_width = 3232; + tiff_bps = 10; + } else if (!strcmp(model,"QV-R41")) { + height = 1720; + width = 2312; + raw_width = 3520; + left_margin = 2; + } else if (!strcmp(model,"QV-R51")) { + height = 1926; + width = 2580; + raw_width = 3904; + } else if (!strcmp(model,"EX-S20")) { + height = 1208; + width = 1620; + raw_width = 2432; + flip = 3; + } else if (!strcmp(model,"EX-S100")) { + height = 1544; + width = 2058; + raw_width = 3136; + } else if (!strcmp(model,"EX-Z50")) { + height = 1931; + width = 2570; + raw_width = 3904; + } else if (!strcmp(model,"EX-Z500")) { + height = 1937; + width = 2577; + raw_width = 3904; + filters = 0x16161616; + } else if (!strcmp(model,"EX-Z55")) { + height = 1960; + width = 2570; + raw_width = 3904; + } else if (!strcmp(model,"EX-Z60")) { + height = 2145; + width = 2833; + raw_width = 3584; + filters = 0x16161616; + tiff_bps = 10; + } else if (!strcmp(model,"EX-Z75")) { + height = 2321; + width = 3089; + raw_width = 4672; + maximum = 0xfff; + } else if (!strcmp(model,"EX-Z750")) { + height = 2319; + width = 3087; + raw_width = 4672; + maximum = 0xfff; + } else if (!strcmp(model,"EX-Z850")) { + height = 2468; + width = 3279; + raw_width = 4928; + maximum = 0xfff; + } else if (!strcmp(model,"EX-Z8")) { + height = 2467; + width = 3281; + raw_height = 2502; + raw_width = 4992; + maximum = 0xfff; + } else if (fsize == 15499264) { /* EX-Z1050 or EX-Z1080 */ + height = 2752; + width = 3672; + raw_width = 5632; + } else if (!strcmp(model,"EX-P505")) { + height = 1928; + width = 2568; + raw_width = 3852; + maximum = 0xfff; + } else if (fsize == 9313536) { /* EX-P600 or QV-R61 */ + height = 2142; + width = 2844; + raw_width = 4288; + } else if (!strcmp(model,"EX-P700")) { + height = 2318; + width = 3082; + raw_width = 4672; + } + 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) 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 && colors == 3) + filters |= ((filters >> 2 & 0x22222222) | + (filters << 2 & 0x88888888)) & filters << 1; +notraw: + if (flip == -1) flip = tiff_flip; + if (flip == -1) 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 function */ + +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..71a37d7b2 --- /dev/null +++ b/rtengine/dcraw.h @@ -0,0 +1,376 @@ +/* + * 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) + ,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; + 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] ; + + 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 panasonic_load_raw(); +void olympus_load_raw(); +void minolta_rd175_load_raw(); +void quicktake_100_load_raw(); +void kodak_radc_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 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); +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 + +}; + + +#endif //DCRAW_H diff --git a/rtengine/dcraw.patch b/rtengine/dcraw.patch new file mode 100644 index 000000000..bfef0fcfa --- /dev/null +++ b/rtengine/dcraw.patch @@ -0,0 +1,2196 @@ +--- C:/GCC/RT/RTSrc/rtengine/dcraw.c Mon Aug 13 19:33:25 2012 ++++ C:/GCC/RT/RTSrc/rtengine/dcraw.cc Mon Aug 13 19:45:38 2012 +@@ -1,5 +1,17 @@ ++/*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-2012 by Dave Coffin, dcoffin a cybercom o net + + This is a command-line ANSI C program to convert raw photos from +@@ -27,21 +39,21 @@ + + #ifndef _GNU_SOURCE + #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 + + #ifdef NODEPS + #define NO_JASPER + #define NO_JPEG +@@ -96,90 +108,40 @@ + + #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 ++#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; +-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=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; +-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]; +-int mask[8][4], flip, tiff_flip, colors; +-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 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; } + + /* + In order to inline this calculation, I make the risky + assumption that all filter patterns can be described +@@ -248,11 +210,11 @@ + { 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 } }; +- static const char filter2[6][6] = ++ static const char filter2[6][6] = + { { 1,1,0,1,1,2 }, + { 1,1,2,1,1,0 }, + { 2,0,1,0,2,1 }, + { 1,1,2,1,1,0 }, + { 1,1,0,1,1,2 }, +@@ -291,10 +253,11 @@ + 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 */ +@@ -364,11 +327,11 @@ + + 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); ++ swab ((char*)pixel, (char*)pixel, count*2); + } + + void CLASS canon_600_fixed_wb (int temp) + { + static const short mul[4][5] = { +@@ -511,11 +474,10 @@ + 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; +@@ -540,14 +502,14 @@ + + /* + getbits(-1) initializes the buffer + getbits(n) where 0 <= n <= 25 returns an n-bit integer + */ +-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 == -1) + return bitbuf = vbits = reset = 0; + if (nbits == 0 || vbits < 0) return 0; +@@ -1221,18 +1183,19 @@ + int CLASS minolta_z2() + { + 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() + { + char *thumb; + thumb_length = thumb_width*thumb_height*3; +@@ -1308,10 +1271,11 @@ + } + 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; + } +@@ -1506,14 +1470,14 @@ + raw_image[i+0] = (a & mask) | (b & ~mask); + raw_image[i+1] = (b & mask) | (a & ~mask); + } + } + +-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) + return bitbuf = vbits = 0; + if (nbits == 0) return 0; +@@ -1572,11 +1536,11 @@ + 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; + } + +@@ -1611,12 +1575,12 @@ + { + 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()"); ++ 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); +@@ -1624,11 +1588,11 @@ + } + 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++) ++ for (col=0; col < width; col++) + image[row*width+col][c] = pixel[col+left_margin]; + } + if (!filters) { + maximum = 0xffff; + raw_color = 1; +@@ -1676,11 +1640,11 @@ + 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]; ++ image[r*width+c][FC(row,col)] = pixel[col]; + } + } + } + free (pixel); + shrink = filters = 0; +@@ -1751,14 +1715,14 @@ + } + free (data); + 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; + if (!vbits) { + fread (buf+load_flags, 1, 0x4000-load_flags, ifp); +@@ -2044,15 +2008,15 @@ + #else + + 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; + } + +@@ -2367,13 +2331,13 @@ + 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) ++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; + pad[3] = pad[3] << 1 | (pad[0]^pad[2]) >> 31; +@@ -2656,11 +2620,11 @@ + + /* RESTRICTED code starts here */ + + void CLASS foveon_decoder (unsigned size, unsigned code) + { +- static unsigned huff[1024]; ++/*RT static unsigned huff[1024];*/ + struct decode *cur; + int i, len; + + if (!code) { + for (i=0; i < size; i++) +@@ -3743,11 +3707,11 @@ + 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++) ++ 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++) +@@ -3959,375 +3923,11 @@ + 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 == 2) 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 == 2) 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); +- } +-} +- +-/* +- Adaptive Homogeneity-Directed interpolation is based on +- the work of Keigo Hirakawa, Thomas Parks, and Paul Lee. +- */ +-#define TS 256 /* Tile Size */ +- +-void CLASS ahd_interpolate() +-{ +- int i, j, k, top, left, row, col, tr, tc, c, d, val, hm[2]; +- ushort (*pix)[4], (*rix)[3]; +- static const int dir[4] = { -1, 1, -TS, TS }; +- unsigned ldiff[2][4], abdiff[2][4], leps, abeps; +- float r, cbrt[0x10000], xyz[3], xyz_cam[3][4]; +- ushort (*rgb)[TS][TS][3]; +- short (*lab)[TS][TS][3], (*lix)[3]; +- char (*homo)[TS][TS], *buffer; +- +- if (verbose) fprintf (stderr,_("AHD interpolation...\n")); +- +- 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]; +- +- border_interpolate(5); +- buffer = (char *) malloc (26*TS*TS); /* 1664 kB */ +- 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]; +- xyz[0] = xyz[1] = xyz[2] = 0.5; +- 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] = cbrt[CLIP((int) xyz[0])]; +- xyz[1] = cbrt[CLIP((int) xyz[1])]; +- xyz[2] = cbrt[CLIP((int) xyz[2])]; +- lix[0][0] = 64 * (116 * xyz[1] - 16); +- lix[0][1] = 64 * 500 * (xyz[0] - xyz[1]); +- lix[0][2] = 64 * 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] = +- (rgb[0][tr][tc][c] + rgb[1][tr][tc][c]) >> 1; +- } +- } +- } +- free (buffer); +-} +-#undef TS +- ++/* RT: delete interpolation function */ + void CLASS median_filter() + { + ushort (*pix)[4]; + int pass, c, i, j, k, med[9]; + static const uchar opt[] = /* Optimal 9-element median search */ +@@ -4491,11 +4091,11 @@ + if (tag == tlen) thumb_length = get4(); + fseek (ifp, save, SEEK_SET); + } + } + +-int CLASS parse_tiff_ifd (int base); ++/*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, +@@ -5008,12 +4608,12 @@ + 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); ++/*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; +@@ -5023,11 +4623,11 @@ + 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; ++/*RT*/ IMFILE *sfp; + + if (tiff_nifds >= sizeof tiff_ifd / sizeof tiff_ifd[0]) + return 1; + ifd = tiff_nifds++; + for (j=0; j < 4; j++) +@@ -5455,16 +5055,17 @@ + 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); ++/*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); +- } ++// fclose (ifp); ++// } + ifp = sfp; + free (buf); + } + for (i=0; i < colors; i++) + FORCC cc[i][c] *= ab[i]; +@@ -5485,10 +5086,12 @@ + + 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())) { +@@ -5558,11 +5161,11 @@ + } 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; ++ load_raw = &CLASS packed_load_raw; break; + case 14: load_flags = 0; + case 16: load_raw = &CLASS unpacked_load_raw; break; + } + break; + case 6: case 7: case 99: +@@ -5665,11 +5268,11 @@ + */ + void CLASS parse_external_jpeg() + { + const char *file, *ext; + char *jname, *jfile, *jext; +- FILE *save=ifp; ++/*RT*/ IMFILE *save=ifp; + + ext = strrchr (ifname, '.'); + file = strrchr (ifname, '/'); + if (!file) file = strrchr (ifname, '\\'); + if (!file) file = ifname-1; +@@ -5687,17 +5290,18 @@ + memcpy (jfile+4, file, 4); + } + } 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); + thumb_offset = 0; + is_raw = 1; +@@ -6031,11 +5635,15 @@ + raw_width = get2(); + } + order = get2(); + hlen = get4(); + if (get4() == 0x48454150) /* "HEAP" */ +- parse_ciff (save+hlen, len-hlen); ++/*RT*/ { ++/*RT*/ ciff_base = save+hlen; ++/*RT*/ ciff_len = len-hlen; ++ parse_ciff (save+hlen, len-hlen); ++/*RT*/ } + if (parse_tiff (save+6)) apply_tiff(); + fseek (ifp, save+len, SEEK_SET); + } + return 1; + } +@@ -6283,11 +5891,12 @@ + */ + void CLASS adobe_coeff (const char *make, const char *model) + { + 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 } }, + { "Apple QuickTake", 0, 0, /* DJC */ + { 21392,-5653,-3353,2406,8010,-415,7166,1427,2078 } }, +@@ -6297,44 +5906,44 @@ + { 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, ++ { "Canon EOS 5D Mark III", 0, 0x3a98, /* RT */ + { 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 7D", 0, 0x3510, +- { 6844,-996,-856,-3876,11761,2396,-593,1772,6198 } }, ++ { "Canon EOS 5D", 0, 0xe6c, /* RT */ ++ { 6319,-793,-614,-5809,13342,2738,-1132,1559,7971 } }, ++ { "Canon EOS 7D", 0, 0x3510, /* RT - Colin Walker */ ++ { 5962,-171,-732,-4189,12307,2099,-911,1981,6304 } }, + { "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 20D", 0, 0xfff, /* RT */ ++ { 7590,-1646,-673,-4697,12411,2568,-627,1118,7295 } }, + { "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 40D", 0, 0x3f60, /* RT */ ++ { 6070,-531,-883,-5763,13647,2315,-1533,2582,6801 } }, + { "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 60D", 0, 0x2ff7, /* RT - Colin Walker */ ++ { 5678,-179,-718,-4389,12381,2243,-869,1819,6380 } }, + { "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 450D", 0, 0x390d, /* RT */ ++ { 6246,-1272,-523,-5075,12357,3075,-1035,1825,7333 } }, + { "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 550D", 0, 0x3dd7, /* RT - Lebedev*/ ++ { 6519,-772,-703,-4994,12737,2519,-1387,2492,6175 } }, + { "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 1000D", 0, 0xe43, +@@ -6345,12 +5954,12 @@ + { 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 III", 0, 0x3bb0, /* RT */ ++ { 7406,-1592,-646,-4856,12457,2698,-432,726,7921 } }, + { "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, +@@ -6365,16 +5974,16 @@ + { 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 G10", 0, 0, /* RT */ ++ { 12535,-5030,-796,-2711,10134,3006,-413,1605,5264 } }, + { "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 G12", 0, 0, /* RT */ ++ { 12222,-4097,-1380,-2876,11016,2130,-888,1630,4434 } }, + { "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, +@@ -6428,11 +6037,11 @@ + { "Canon PowerShot S3 IS", 0, 0, /* DJC */ + { 14062,-5199,-1446,-4712,12470,2243,-1286,2028,4836 } }, + { "Canon PowerShot SX1 IS", 0, 0, + { 6578,-259,-502,-5974,13030,3309,-308,1058,4970 } }, + { "Canon PowerShot SX110 IS", 0, 0, /* DJC */ +- { 14134,-5576,-1527,-1991,10719,1273,-1158,1929,3581 } }, ++ { 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 */ +@@ -6505,12 +6114,12 @@ + { 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 X100", 0, 0, +- { 12161,-4457,-1069,-5034,12874,2400,-795,1724,6904 } }, ++ { "FUJIFILM X100", 0, 0, /* RT - Colin Walker */ ++ { 10841,-3288,-807,-4652,12552,2344,-642,1355,7206 } }, + { "FUJIFILM X10", 0, 0, + { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, + { "FUJIFILM X-Pro1", 0, 0, + { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, + { "FUJIFILM X-S1", 0, 0, +@@ -6611,28 +6220,26 @@ + { 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 D200", 0, 0xfbc, /* RT */ ++ { 8498,-2633,-295,-5423,12869,2860,-777,1077,8124 } }, + { "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, 0, +- { 7013,-1408,-635,-5268,12902,2640,-1470,2801,7379 } }, ++ { "NIKON D3000", 0, 0, /* RT */ ++ { 9211,-2521,-104,-6487,14280,2394,-754,1122,8033 } }, ++ { "NIKON D3100", 0, 0, /* RT */ ++ { 7729,-2212,-481,-5709,13148,2858,-1295,1908,8936 } }, + { "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 D3S", 0, 0, /* RT */ ++ { 8792,-2663,-344,-5221,12764,2752,-1491,2165,8121 } }, + { "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, +@@ -6645,14 +6252,14 @@ + { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } }, + { "NIKON D50", 0, 0, + { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } }, + { "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 D700", 0, 0, +- { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } }, ++ { "NIKON D7000", 0, 0, /* RT - Tanveer(tsk1979) */ ++ { 7530,-1942,-255,-4318,11390,3362,-926,1694,7649 } }, ++ { "NIKON D700", 0, 0, /* RT */ ++ { 8364,-2503,-352,-6307,14026,2492,-1134,1512,8156 } }, + { "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, +@@ -6711,12 +6318,12 @@ + { 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-30", 0, 0xfbc, /* RT - Colin Walker */ ++ { 8510,-2355,-693,-4819,12520,2578,-1029,2067,7752 } }, + { "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, +@@ -6729,30 +6336,30 @@ + { 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, 0, +- { 11200,-3783,-1325,-4576,12593,2206,-695,1742,7504 } }, ++ { "OLYMPUS E-5", 0, 0, /* RT - Colin Walker */ ++ { 9732,-2629,-999,-4899,12931,2173,-1243,2353,7457 } }, + { "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, 0, +- { 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-P1", 0, 0xffd, /* RT - Colin Walker */ ++ { 8834,-2344,-804,-4691,12503,2448,-978,1919,7603 } }, ++ { "OLYMPUS E-P2", 0, 0xffd, /* RT - Colin Walker */ ++ { 7758,-1619,-800,-5002,12886,2349,-985,1964,8305 } }, ++ { "OLYMPUS E-P3", 0, 0, /* RT - Colin Walker */ ++ { 7041,-1794,-336,-3790,11192,2984,-1364,2625,6217 } }, ++ { "OLYMPUS E-PL1s", 0, 0, /* RT - Colin Walker */ ++ { 9010,-2271,-838,-4792,12753,2263,-1059,2058,7589 } }, ++ { "OLYMPUS E-PL1", 0, 0, /* RT - Colin Walker */ ++ { 9010,-2271,-838,-4792,12753,2263,-1059,2058,7589 } }, ++ { "OLYMPUS E-PL2", 0, 0, /* RT - Colin Walker */ ++ { 11975,-3351,-1184,-4500,12639,2061,-1230,2353,7009 } }, ++ { "OLYMPUS E-PL3", 0, 0, /* RT - Colin Walker */ ++ { 7041,-1794,-336,-3790,11192,2984,-1364,2625,6217 } }, + { "OLYMPUS E-PM1", 0, 0, + { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } }, + { "OLYMPUS E-M5", 0, 0, + { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, + { "OLYMPUS SP350", 0, 0, +@@ -6767,12 +6374,12 @@ + { 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-1", 0, 0, +- { 10901,-4095,-1074,-1141,9208,2293,-62,1417,5158 } }, ++ { "OLYMPUS XZ-1", 0, 0, /* RT - Colin Walker */ ++ { 8665,-2247,-762,-2424,10372,2382,-1011,2286,5189 } }, + { "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, +@@ -6785,12 +6392,12 @@ + { 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 K200D", 0, 0, /* RT */ ++ { 10962,-4428,-542,-5486,13023,2748,-569,842,8390 } }, + { "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, +@@ -6843,40 +6450,42 @@ + { 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 } }, ++ { "Leica Camera AG M9 Digital Camera", 0, 0, /* RT */ ++ { 7181,-1706,-55,-3557,11409,2450,-621,2072,7533 } }, + { "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 } }, ++ { "Panasonic DMC-FZ150", 143, 0xfff, /* RT */ ++ { 10435,-3208,-72,-2293,10506,2067,-486,1725,4682 } }, + { "LEICA V-LUX 3", 143, 0xfff, + { 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } }, + { "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-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-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-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-GF5", 143, 0xfff, + { 8228,-2945,-660,-3938,11792,2430,-1094,2278,5793 } }, +- { "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-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 } }, + { "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, +@@ -6937,26 +6546,24 @@ + { 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-A700", 126, 0, /* RT */ ++ { 6509,-1333,-137,-6171,13621,2824,-1490,2226,6952 } }, + { "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-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 DSLR-A900", 128, 0, /* RT */ ++ { 5715,-1433,-410,-5603,12937,2989,-644,1247,8372 } }, ++ { "SONY NEX-5N", 138, 0, /* RT - Colin Walker */ ++ { 5130,-1055,-269,-4473,11797,3050,-701,1310,7121 } }, ++ { "SONY NEX-C3", 128, 0, /* RT - Colin Walker */ ++ { 5130,-1055,-269,-4473,11797,3050,-701,1310,7121 } }, ++ { "SONY NEX-3", 128, 0, /* RT - Colin Walker */ ++ { 5145,-741,-123,-4915,12310,2945,-794,1489,6906 } }, ++ { "SONY NEX-5", 128, 0, /* RT - Colin Walker */ ++ { 5154,-716,-115,-5065,12506,2882,-988,1715,6800 } }, + { "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, +@@ -6966,15 +6573,15 @@ + { "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 } }, ++ { 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-A77", 128, 0, /* RT - Colin Walker */ ++ { 5126,-830,-261,-4788,12196,2934,-948,1602,7068 } } + }; + double cam_xyz[4][3]; + char name[130]; + int i, j; + +@@ -7218,17 +6825,26 @@ + 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))) { ++ ++ /*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); + } 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); +@@ -7269,10 +6885,11 @@ + } + 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)) { +@@ -7366,11 +6983,11 @@ + 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; } ++/*RT*/ { width = 4308; filters = 0x16161616; } + if (width >= 4960 && !strcmp(model,"K-5")) + { 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")) +@@ -7770,11 +7387,11 @@ + height -= top_margin; + width -= left_margin; + } else if (is_canon && raw_width == 5920) { + height = 3870; + width = 5796; +- top_margin = 80; ++ top_margin = 80; + left_margin = 122; + } else if (!strcmp(model,"D1")) { + cam_mul[0] *= 256/527.0; + cam_mul[2] *= 256/317.0; + } else if (!strcmp(model,"D1X")) { +@@ -7799,11 +7416,11 @@ + width -= 42; + } else if (!strcmp(model,"D5100") || + !strcmp(model,"D7000")) { + width -= 44; + } else if (!strcmp(model,"D3200") || +- !strcmp(model,"D800")) { ++ !strcmp(model,"D800") || !strcmp(model,"D800E") ) { + width -= 46; + } else if (!strcmp(model,"D4")) { + width -= 52; + left_margin = 2; + } else if (!strncmp(model,"D40",3) || +@@ -8696,198 +8313,11 @@ + 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 (wide*high, 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 function */ + + struct tiff_tag { + ushort tag, type; + int count; + union { char c[4]; short s[2]; int i; } val; +@@ -8907,572 +8337,13 @@ + 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; /* "-h" implies "-f" */ +- 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))); +- if (document_mode == 3) { +- top_margin = left_margin = fuji_width = 0; +- height = raw_height; +- if (width <= raw_width * 8 / tiff_bps) +- width = raw_width * 8 / tiff_bps; +- else width = raw_width; +- } +- iheight = (height + shrink) >> shrink; +- iwidth = (width + shrink) >> shrink; +- if (identify_only) { +- if (verbose) { +- 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; +- } +- image = (ushort (*)[4]) calloc (iheight*iwidth, sizeof *image); +- merror (image, "main()"); +- 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()"); +- } +- 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 (raw_image) { +- 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 || filters < 1000) +- vng_interpolate(); +- else if (quality == 2) +- ppg_interpolate(); +- else ahd_interpolate(); +- } +- if (mix_green) +- for (colors=3, i=0; i < height*width; i++) +- image[i][1] = (image[i][1] + image[i][3]) >> 1; +- if (!is_foveon && colors == 3) median_filter(); +- if (!is_foveon && highlight == 2) blend_highlights(); +- if (!is_foveon && highlight > 2) recover_highlights(); +- if (use_fuji_rotate) fuji_rotate(); +-#ifndef NO_LCMS +- if (cam_profile) apply_profile (cam_profile, out_profile); +-#endif +- convert_to_rgb(); +- if (use_fuji_rotate) stretch(); +-thumbnail: +- if (write_fun == &CLASS jpeg_thumb) +- write_ext = ".jpg"; +- else if (output_tiff && write_fun == &CLASS write_ppm_tiff) +- write_ext = ".tiff"; +- else +- write_ext = ".pgm\0.ppm\0.ppm\0.pam" + colors*5-5; +- ofname = (char *) malloc (strlen(ifname) + 64); +- merror (ofname, "main()"); +- if (write_to_stdout) +- strcpy (ofname,_("standard output")); +- else { +- strcpy (ofname, ifname); +- if ((cp = strrchr (ofname, '.'))) *cp = 0; +- if (multi_out) +- sprintf (ofname+strlen(ofname), "_%0*d", +- snprintf(0,0,"%d",is_raw-1), shot_select); +- if (thumbnail_only) +- strcat (ofname, ".thumb"); +- strcat (ofname, write_ext); +- ofp = fopen (ofname, "wb"); +- if (!ofp) { +- status = 1; +- perror (ofname); +- goto cleanup; +- } +- } +- if (verbose) +- fprintf (stderr,_("Writing data to %s ...\n"), ofname); +- (*write_fun)(); +- fclose(ifp); +- if (ofp != stdout) fclose(ofp); +-cleanup: +- if (meta_data) free (meta_data); +- if (ofname) free (ofname); +- if (oprof) free (oprof); +- if (image) free (image); +- if (multi_out) { +- if (++shot_select < is_raw) arg--; +- else shot_select = 0; +- } +- } +- return status; +-} ++/* RT: Delete from here */ ++/*RT*/#undef SQR ++/*RT*/#undef MAX ++/*RT*/#undef MIN ++/*RT*/#undef ABS ++/*RT*/#undef LIM ++/*RT*/#undef ULIM ++/*RT*/#undef CLIP diff --git a/rtengine/dcraw.patch.README b/rtengine/dcraw.patch.README new file mode 100644 index 000000000..22b2323d7 --- /dev/null +++ b/rtengine/dcraw.patch.README @@ -0,0 +1,8 @@ +Patch for vanilla dcraw. Please run this against any new dcraw version copied here. + Instructions for patching: +1) Download newest dcraw.c file, and copy to this folder. +2) Run 'patch -p0 < dcraw.patch' to patch the file. If there are any rejections, please fix them manually. +3) Move the patched dcraw.c to dcraw.cc +4) Re-copy the vanilla downloaded dcraw.c back to this folder, and update the patch: 'diff -u dcraw.c dcraw.cc > dcraw.patch' + + diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc new file mode 100644 index 000000000..8fdb42f22 --- /dev/null +++ b/rtengine/dcrop.cc @@ -0,0 +1,433 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#include "dcrop.h" +#include "curves.h" +#include "mytime.h" +#include "refreshmap.h" +#include "rt_math.h" + +#define SKIPS(a,b) ((a) / (b) + ((a) % (b) > 0)) + +namespace rtengine { + +extern const Settings* settings; + +Crop::Crop (ImProcCoordinator* parent) + : resizeCrop(NULL), transCrop(NULL), updating(false), + skip(10),cropw(-1), croph(-1), trafw(-1), trafh(-1), + borderRequested(32), cropAllocated(false), + cropImageListener(NULL), parent(parent) +{ + parent->crops.push_back (this); +} + +Crop::~Crop () { + + cropMutex.lock (); + parent->mProcessing.lock (); + std::vector::iterator i = std::find (parent->crops.begin(), parent->crops.end(), this); + if (i!=parent->crops.end ()) + parent->crops.erase (i); + + freeAll (); + parent->mProcessing.unlock (); + cropMutex.unlock (); +} + +void Crop::setListener (DetailedCropListener* il) { + // We can make reads in the IF, because the mProcessing lock is only needed for change + if (cropImageListener!=il) { + Glib::Mutex::Lock lock(cropMutex); + cropImageListener = il; + } +} + +void Crop::update (int todo) { + Glib::Mutex::Lock lock(cropMutex); + + ProcParams& params = parent->params; + + // 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; + + // set improcfuncions' scale now that skip has been updated + parent->ipf.setScale (skip); + + baseCrop = origCrop; + + bool needstransform = parent->ipf.needsTransform(); + + if (todo & (M_INIT|M_LINDENOISE)) { + Glib::Mutex::Lock 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.hlrecovery, params.icm, params.raw ); + + //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->convertColorSpace(origCrop, params.icm, params.raw); +} + + // transform + if ((!needstransform && transCrop) || (transCrop && (transCrop->width!=cropw || transCrop->height!=croph))) { + delete transCrop; + transCrop = NULL; + } + if (needstransform && !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->imgsrc->getMetaData()->getFocalLen(), parent->imgsrc->getMetaData()->getFocalLen35mm(), + parent->imgsrc->getMetaData()->getFocusDist(), parent->imgsrc->getRotateDegree(), false); + if (transCrop) + baseCrop = transCrop; + + // 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()); + }*/ + + 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 ); + + /*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.EPDToneMap(labnCrop, 5, 1); //Go with much fewer than normal iterates for fast redisplay. + + // parent->ipf.luminanceCurve (labnCrop, labnCrop, parent->lumacurve); + bool utili=false; + bool autili=false; + bool butili=false; + bool ccutili=false; + bool cclutili=false; + CurveFactory::complexsgnCurve (autili, butili,ccutili,cclutili, params.labCurve.chromaticity, params.labCurve.rstprotection, + params.labCurve.acurve, params.labCurve.bcurve,params.labCurve.cccurve,params.labCurve.lccurve, parent->chroma_acurve, parent->chroma_bcurve, parent->satcurve,parent->lhskcurve, 1); + + parent->ipf.chromiLuminanceCurve (labnCrop, labnCrop, parent->chroma_acurve, parent->chroma_bcurve, parent->satcurve, parent->lhskcurve, parent->lumacurve, utili, autili, butili, ccutili,cclutili); + //parent->ipf.colorCurve (labnCrop, labnCrop); + parent->ipf.vibrance (labnCrop); + + if (skip==1) { + parent->ipf.impulsedenoise (labnCrop); + parent->ipf.defringe (labnCrop); + parent->ipf.MLsharpen (labnCrop); + parent->ipf.MLmicrocontrast (labnCrop); + //parent->ipf.MLmicrocontrast (labnCrop); + parent->ipf.sharpening (labnCrop, (float**)cbuffer); + parent->ipf.dirpyrequalizer (labnCrop); + } + } + + // 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); + + 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) { + delete origCrop; + if (transCrop) + delete transCrop; + transCrop = NULL; + if (resizeCrop) + delete resizeCrop; + resizeCrop = NULL; + delete laboCrop; + delete labnCrop; + delete cropImg; + delete cshmap; + //for (int i=0; iverbose) 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); + laboCrop = new LabImage (cropw, croph); + labnCrop = new LabImage (cropw, croph); + cropImg = new Image8 (cropw, croph); + + cshmap = new SHMap (cropw, croph, true); + + 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; +} + +// Try a simple, threadless update flag first +bool Crop::tryUpdate() { + bool needsFullUpdate = true; + + // If there are more update request, the following WHILE will collect it + if (updating) { + needsNext = true; + needsFullUpdate = false; + } else updating = true; + + return needsFullUpdate; +} + +// Full update, should be called via thread +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); + + needsNext = true; + while (needsNext) { + needsNext = false; + update (ALL); + } + updating = false; + + if (parent->plistener) + parent->plistener->setProgressState (false); +} + +} + diff --git a/rtengine/dcrop.h b/rtengine/dcrop.h new file mode 100644 index 000000000..5647d91a2 --- /dev/null +++ b/rtengine/dcrop.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 _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" + +namespace rtengine { + +using namespace procparams; + +class ImProcCoordinator; + +class Crop : public DetailedCrop { + + protected: + Imagefloat* origCrop, *baseCrop; + Imagefloat* *resizeCrop, *transCrop; + LabImage *laboCrop, *labnCrop; + Image8 *cropImg; // permanently allocated in RAM and only renewed on size changes + + float** cbuffer; + float * cbuf_real; + SHMap* cshmap; + + bool updating, needsNext; + 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; + Glib::Mutex 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); } + + bool tryUpdate (); // First try, only make fullUpdate if this returns false + 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..202da7b11 --- /dev/null +++ b/rtengine/demosaic_algos.cc @@ -0,0 +1,1764 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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" + +#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 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 ("Demosaicing..."); + 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 = 2*65536; + cache = new double[maxindex]; + threshold = (int)(0.008856*MAXVAL); + 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 ("Demosaicing..."); + 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 ("Demosaicing..."); + 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) { + plistener->setProgressStr ("Demosaicing..."); + 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]; + } +} + +/* + 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 ("AHD Demosaicing..."); + 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] + 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; iverbose) printf("Refinement Lassus\n"); + + MyTime t1e,t2e; + t1e.set(); + int u=W, v=2*u, w=3*u, x=4*u, y=5*u; + float (*image)[4]; + image = (float(*)[4]) calloc(W*H, sizeof *image); +#pragma omp parallel shared(image) + { + // convert red, blue, green to image +#pragma omp for + for (int i=0;isetProgressStr ("Refinement..."); + plistener->setProgress ((float)b/PassCount); + } + + // Reinforce interpolated green pixels on RED/BLUE pixel locations +#pragma omp for + for (int row=6; rowverbose) printf("Refinement %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 ("DCB Demosaicing..."); + 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); + } + } +#pragma omp atomic + tilesDone++; + } + +#ifdef _OPENMP + for(int i=0; isetProgress (1.0); +} +#undef TILEBORDER +#undef TILESIZE +#undef CACHESIZE +} /* namespace */ \ No newline at end of file diff --git a/rtengine/dfmanager.cc b/rtengine/dfmanager.cc new file mode 100644 index 000000000..683e09fd4 --- /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 false; + if( !file->query_exists()) + return false; + 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..545759b4e --- /dev/null +++ b/rtengine/diagonalcurves.cc @@ -0,0 +1,326 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#include +#include +#include "curves.h" +#include +#include +#include "mytime.h" +#include + +#define CLIPD(a) ((a)>0.0?((a)<1.0?(a):1.0):0.0) + +namespace rtengine { + +DiagonalCurve::DiagonalCurve (const std::vector& p, int poly_pn) { + + ppn = poly_pn > 65500 ? 65500 : poly_pn; + bool identity = true; + + if (ppn < 500) hashSize = 100; // Arbitrary cut-off value, but mutliple of 10 + if (ppn < 50) hashSize = 10; // Arbitrary cut-off value, but mutliple of 10 + + if (p.size()<3) { + kind = DCT_Empty; + } + else { + kind = (DiagonalCurveType)p[0]; + if (kind==DCT_Linear || kind==DCT_Spline || kind==DCT_NURBS) { + N = (p.size()-1)/2; + x = new double[N]; + y = new double[N]; + int ix = 1; + for (int i=0; i 2) + spline_cubic_set (); + else if (kind==DCT_NURBS && N > 2) { + NURBS_set (); + fillHash(); + } + else kind=DCT_Linear; + } + } + else if (kind==DCT_Parametric) { + if ((p.size()==8 || p.size()==9) && (p.at(4)!=0.0f || p.at(5)!=0.0f || p.at(6)!=0.0f || p.at(7)!=0.0f)) { + identity = false; + + x = new double[9]; + 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; + } + } + 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 c = -log(2.0)/log(x[2]); + double tv = exp(c*log(t)); + double base = pfull (tv, x[8], x[6], x[5]); + double stretched = base<=1e-14 ? 0.0 : exp(log(base)/c); + + base = pfull (0.5, x[8], x[6], x[5]); + double fc = base<=1e-14 ? 0.0 : exp(log(base)/c); // value of the curve at the center point + 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..470b473b6 --- /dev/null +++ b/rtengine/dirpyr_equalizer.cc @@ -0,0 +1,235 @@ +/* + * 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 _OPENMP +#include +#endif + +#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[abs((int)data_fine[i1][j1]-data_fine[i][j])] ) + +namespace rtengine { + + static const int maxlevel = 4; + 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 ) + { + 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; + + + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + LUTf rangefn(0x10000); + + int intfactor = 1024;//16384; + + + //set up range functions + + for (int i=0; i<0x10000; i++) { + rangefn[i] = (int)((thresh/((double)(i) + thresh))*intfactor); + } + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + int level; + array2D buffer (srcwidth, srcheight); + + multi_array2D dirpyrlo (srcwidth, srcheight); + + + for (int i=0; i 0; level--) + { + idirpyr_eq_channel(dirpyrlo[level], dirpyrlo[level-1], buffer, srcwidth, srcheight, level, mult ); + } + + + scale = scales[0]; + + idirpyr_eq_channel(dirpyrlo[0], dst, buffer, srcwidth, srcheight, 0, mult ); + + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + for (int i=0; inoisehi || 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..70fe5e7cd --- /dev/null +++ b/rtengine/expo_before_b.cc @@ -0,0 +1,152 @@ + +//////////////////////////////////////////////////////////////// +// +// //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 + +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)); + +} \ No newline at end of file diff --git a/rtengine/fast_demo.cc b/rtengine/fast_demo.cc new file mode 100644 index 000000000..ee6031863 --- /dev/null +++ b/rtengine/fast_demo.cc @@ -0,0 +1,266 @@ +//////////////////////////////////////////////////////////////// +// +// 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" +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 ("Fast demosaicing..."); + plistener->setProgress (0.0); + } + float progress = 0.0; + + + const int bord=4; + + int clip_pt = 4*65535*initialGain; + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +#pragma omp parallel + { +#pragma omp for + //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 + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +#pragma omp for + 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); + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + +#pragma omp for + // 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); + + +#pragma omp for + 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); + +#pragma omp barrier + +#pragma omp for + + // 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); + } + +#undef bord + +}//namespace diff --git a/rtengine/ffmanager.cc b/rtengine/ffmanager.cc new file mode 100644 index 000000000..6e5c1c70f --- /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 false; + if( !file->query_exists()) + return false; + 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..77243f1e5 --- /dev/null +++ b/rtengine/flatcurves.cc @@ -0,0 +1,358 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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) : leftTangent(NULL), rightTangent(NULL) { + + ppn = poly_pn > 65500 ? 65500 : poly_pn; + poly_x.clear(); + poly_y.clear(); + + kind = FCT_Empty; + periodic = isPeriodic; + + 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 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(); +} + +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 0.5; + } +} + +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 + +// 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 void gaussHorizontal (T** src, T** dst, AlignedBufferMP &buffer, int W, int H, double sigma) { + + 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 void gaussVertical (T** src, T** dst, AlignedBufferMP &buffer, int W, int H, double sigma) { + + 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" + + +//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/hilite_recon.cc b/rtengine/hilite_recon.cc new file mode 100644 index 000000000..9640675b4 --- /dev/null +++ b/rtengine/hilite_recon.cc @@ -0,0 +1,702 @@ +//////////////////////////////////////////////////////////////// +// +// 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" + + + + +#define FOREACHCOLOR for (int c=0; c < ColorCount; c++) + +//#include "RGBdefringe.cc" + +//namespace rtengine { + + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void RawImageSource::boxblur2(float** src, float** dst, int H, int W, int box ) +{ + + array2D temp(W,H,ARRAY2D_CLEAR_DATA); + + //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,H,ARRAY2D_CLEAR_DATA); + array2D temp1(W,H,ARRAY2D_CLEAR_DATA); + + float maxtmp=0; + +#ifdef _OPENMP +#pragma omp parallel for +#endif + //box blur image channel; box size = 2*box+1 + //horizontal blur + for (int row = 0; row < H; row++) { + int len = box + 1; + temp[row][0] = src[row][0]/len; + maxtmp = max(maxtmp,src[row][0]); + for (int j=1; j<=box; j++) { + temp[row][0] += src[row][j]/len; + maxtmp = max(maxtmp,src[row][j]); + } + for (int col=1; col<=box; col++) { + temp[row][col] = (temp[row][col-1]*len + src[row][col+box])/(len+1); + maxtmp = max(maxtmp,src[row][col]); + 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; + maxtmp = max(maxtmp,src[row][col]); + } + for (int col=W-box; colsetProgressStr ("HL reconstruction..."); + plistener->setProgress (0.0); + } + + 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,hfh,ARRAY2D_CLEAR_DATA); + + boxblur_resamp(red,hfsize[0],chmaxalt[0],height,width,range,pitch); + boxblur_resamp(green,hfsize[1],chmaxalt[1],height,width,range,pitch); + boxblur_resamp(blue,hfsize[2],chmaxalt[2],height,width,range,pitch); + + if(plistener) plistener->setProgress(0.10); + + + + //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); + + // blur RGB channels + boxblur2(red ,channelblur[0],height,width,4); + boxblur2(green,channelblur[1],height,width,4); + boxblur2(blue ,channelblur[2],height,width,4); + + float hipass_sum=0, hipass_norm=0.01; + + // set up which pixels are clipped or near clipping +#ifdef _OPENMP +#pragma omp parallel for +#endif + for (int i=0; ithresh[0] || green[i][j]>thresh[1] || blue[i][j]>thresh[2]) && + (red[i][j]setProgress(0.25); + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //blur highlight data + boxblur2(hilite_full[4],hilite_full[4],height,width,1); + +#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,hfh,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); + + 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) plistener->setProgress(0.50); + + 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]; + } + } + } +#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]; + } + } + } +#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]; + } + } + } +#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)); + } + } + + } + +#ifdef _OPENMP +#pragma omp parallel for +#endif + //fill in edges + for (int dir=0; dirsetProgress(0.75); + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + /*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..4228e224d --- /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..d2c935bf8 --- /dev/null +++ b/rtengine/iccstore.cc @@ -0,0 +1,434 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#include "iccstore.h" +#ifdef WIN32 +#include +#else +#include +#endif +#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 () { + + Glib::Mutex::Lock lock(mutex_); + + std::vector res; + for (std::map::iterator i=fileProfiles.begin(); i!=fileProfiles.end(); i++){ + std::string 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; +} + + +ICCStore* +ICCStore::getInstance(void) +{ + static ICCStore* instance_ = 0; + if ( instance_ == 0 ) + { + static Glib::Mutex smutex_; + Glib::Mutex::Lock 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) { + + Glib::Mutex::Lock 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) { + + Glib::Mutex::Lock 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) { + + Glib::Mutex::Lock lock(mutex_); + + return fileProfileContents[name]; +} + +// Reads all profiles from the given profiles dir +void ICCStore::init (Glib::ustring usrICCDir, Glib::ustring rtICCDir) { + + Glib::Mutex::Lock 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; + } + } + } + } 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 + + } + + // 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..acad32c9d --- /dev/null +++ b/rtengine/iccstore.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 __ICCSTORE__ +#define __ICCSTORE__ + +#include +#include +#include +#include + +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; + + Glib::Mutex mutex_; + + ICCStore (); + void loadICCs(Glib::ustring rootDirName, bool nameUpper, std::map& resultProfiles, std::map &resultProfileContents); + + public: + + static ICCStore* getInstance(void); + + 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.h b/rtengine/iimage.h new file mode 100644 index 000000000..237dbc1a4 --- /dev/null +++ b/rtengine/iimage.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 _IIMAGE_ +#define _IIMAGE_ + +#include +#include + +namespace rtengine { + + class ProgressListener; + + /** This class represents an image (the result of the image processing) */ + class IImage { + public: + /** Returns a mutex that can is useful in many situations. No image operations shuold be performed without locking this mutex. + * @return The mutex */ + virtual Glib::Mutex& getMutex ()=0; + virtual cmsHPROFILE getProfile ()=0; + /** Returns the width of the image. + * @return The width of the image */ + virtual int getWidth ()=0; + /** Returns the height of the image. + * @return The height of the image */ + virtual int getHeight ()=0; + /** Returns the bits per pixel of the image. + * @return The bits per pixel of the image */ + virtual int getBitsPerPixel ()=0; + /** Saves the image to file. It autodetects the format (jpg, tif, png are supported). + * @param fname is the name of the file + @return the error code, 0 if none */ + virtual int saveToFile (Glib::ustring fname)=0; + /** Saves the image to file in a png format. + * @param fname is the name of the file + * @param compression is the amount of compression (0-6), -1 corresponds to the default + * @param bps can be 8 or 16 depending on the bits per pixels the output file will have + @return the error code, 0 if none */ + virtual int saveAsPNG (Glib::ustring fname, int compression = -1, int bps = -1)=0; + /** Saves the image to file in a jpg format. + * @param fname is the name of the file + * @param quality is the quality of the jpeg (0...100), set it to -1 to use default + @return the error code, 0 if none */ + virtual int saveAsJPEG (Glib::ustring fname, int quality = 100, int subSamp = 3 )=0; + /** Saves the image to file in a tif format. + * @param fname is the name of the file + * @param bps can be 8 or 16 depending on the bits per pixels the output file will have + @return the error code, 0 if none */ + virtual int saveAsTIFF (Glib::ustring fname, int bps = -1, bool uncompressed = false)=0; + /** Sets the progress listener if you want to follow the progress of the image saving operations (optional). + * @param pl is the pointer to the class implementing the ProgressListener interface */ + virtual void setSaveProgressListener (ProgressListener* pl)=0; + /** Free the image */ + virtual void free ()=0; + }; + + /** This class represents an image having a classical 8 bits/pixel representation */ + class IImage8 : public IImage { + public: + /** Returns the pixel data, in r/g/b order from top left to bottom right continously. + * @return a pointer to the pixel data */ + virtual const unsigned char* getData ()=0; + }; + + /** 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 8-byte alignment. */ + class IImage16 : public IImage { + public: + /** Returns the "red" plane data. + * @return the two dimensional array of the red plane */ + virtual unsigned short** getRPlane ()=0; + /** Returns the "green" plane data. + * @return the two dimensional array of the green plane */ + virtual unsigned short** getGPlane ()=0; + /** Returns the "blue" plane data. + * @return the two dimensional array of the blue plane */ + virtual unsigned short** getBPlane ()=0; + }; + + /** This class represents an image having a float pixel planar representation. + The planes are stored as two dimensional arrays. All the rows have a 8-byte alignment. */ + class IImagefloat : public IImage { + public: + /** Returns the "red" plane data. + * @return the two dimensional array of the red plane */ + virtual float** getRPlane ()=0; + /** Returns the "green" plane data. + * @return the two dimensional array of the green plane */ + virtual float** getGPlane ()=0; + /** Returns the "blue" plane data. + * @return the two dimensional array of the blue plane */ + virtual float** getBPlane ()=0; + }; +} + +#endif diff --git a/rtengine/image16.cc b/rtengine/image16.cc new file mode 100644 index 000000000..890a90164 --- /dev/null +++ b/rtengine/image16.cc @@ -0,0 +1,297 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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 () + : unaligned (NULL), data (NULL), r (NULL), g (NULL), b (NULL){ +} + +Image16::Image16 (int w, int h) + : unaligned (NULL), width(w), height (h), data (NULL), r (NULL), g (NULL), b (NULL) { + + allocate (w, h); +} + +Image16::~Image16 () { + + if (data!=NULL) { + delete [] data; + delete [] r; + delete [] g; + delete [] b; + } +} + +void Image16::allocate (int W, int H) { + + width=W; + height=H; + if (data!=NULL) { + delete [] data; + delete [] r; + delete [] g; + delete [] b; + } + + r = new unsigned short*[height]; + g = new unsigned short*[height]; + b = new unsigned short*[height]; + data = new unsigned short[W*H*3]; + + rowstride = W; + planestride = rowstride * height; + + unsigned short* redstart = data + 0*planestride; + unsigned short* greenstart = data + 1*planestride; + unsigned short* bluestart = data + 2*planestride; + + + 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) { + + if (data==NULL) + return; + + if (bps==8) { + int ix = 0; + for (int i=0; ir[i], r[i], width*sizeof(unsigned short)); + memcpy (cp->g[i], g[i], width*sizeof(unsigned short)); + memcpy (cp->b[i], b[i], width*sizeof(unsigned short)); + } + + return cp; +} + +Image16* Image16::rotate (int deg) { + + if (deg==90) { + Image16* result = new Image16 (height, width); + for (int i=0; ir[i][j] = r[height-1-j][i]; + result->g[i][j] = g[height-1-j][i]; + result->b[i][j] = b[height-1-j][i]; + } + return result; + } + else if (deg==270) { + Image16* result = new Image16 (height, width); + for (int i=0; ir[i][j] = r[j][width-1-i]; + result->g[i][j] = g[j][width-1-i]; + result->b[i][j] = b[j][width-1-i]; + } + return result; + } + else if (deg==180) { + Image16* result = new Image16 (width, height); + for (int i=0; ir[i][j] = r[height-1-i][width-1-j]; + result->g[i][j] = g[height-1-i][width-1-j]; + result->b[i][j] = b[height-1-i][width-1-j]; + } + return result; + } + else + return NULL; +} + +Image16* Image16::hflip () { + + Image16* result = new Image16 (width, height); + for (int i=0; ir[i][j] = r[i][width-1-j]; + result->g[i][j] = g[i][width-1-j]; + result->b[i][j] = b[i][width-1-j]; + } + return result; + +} + +Image16* Image16::vflip () { + + Image16* result = new Image16 (width, height); + for (int i=0; ir[i][j] = r[height-1-i][j]; + result->g[i][j] = g[height-1-i][j]; + result->b[i][j] = b[height-1-i][j]; + } + return result; + +} + +Image16* Image16::resize (int nw, int nh, TypeInterpolation interp) { + + if (interp == TI_Nearest) { + Image16* res = new Image16 (nw, nh); + for (int i=0; ir[i][j] = r[ri][ci]; + res->g[i][j] = g[ri][ci]; + res->b[i][j] = b[ri][ci]; + } + } + return res; + } + else if (interp == TI_Bilinear) { + Image16* res = new Image16 (nw, nh); + for (int i=0; i=height) sy = height-1; + double dy = (double)i*height/nh - sy; + int ny = sy+1; + if (ny>=height) ny = sy; + for (int j=0; j=width) sx = width; + double dx = (double)j*width/nw - sx; + int nx = sx+1; + if (nx>=width) nx = sx; + res->r[i][j] = r[sy][sx]*(1-dx)*(1-dy) + r[sy][nx]*dx*(1-dy) + r[ny][sx]*(1-dx)*dy + r[ny][nx]*dx*dy; + res->g[i][j] = g[sy][sx]*(1-dx)*(1-dy) + g[sy][nx]*dx*(1-dy) + g[ny][sx]*(1-dx)*dy + g[ny][nx]*dx*dy; + res->b[i][j] = b[sy][sx]*(1-dx)*(1-dy) + b[sy][nx]*dx*(1-dy) + b[ny][sx]*(1-dx)*dy + b[ny][nx]*dx*dy; + } + } + return res; + } + return NULL; +} + +Image8* +Image16::to8() const +{ + Image8* img8 = new Image8(width,height); + for ( int h = 0; h < height; ++h ) + { + for ( int w = 0; w < width; ++w ) + { + img8->r(h,w,r[h][w] >> 8); + img8->g(h,w,g[h][w] >> 8); + img8->b(h,w,b[h][w] >> 8); + } + } + return img8; +} + +Imagefloat* +Image16::tofloat() const +{ + 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 parallize planar setups + // so build temporary buffers to allow multi processor execution + #pragma omp parallel for + 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 { + +enum TypeInterpolation { TI_Nearest, TI_Bilinear }; + +class Image8; + +class Image16 : public ImageIO, public IImage16 { + + private: + unsigned char* unaligned; + + public: + int rowstride; + int planestride; + + int width; + int height; + + unsigned short* data; + + unsigned short** r; + unsigned short** g; + unsigned short** b; + + + Image16 (); + Image16 (int width, int height); + ~Image16 (); + + Image16* copy (); + + Image8* to8() const; + Imagefloat* tofloat() const; + + Image16* rotate (int deg); + Image16* hflip (); + Image16* vflip (); + Image16* resize (int nw, int nh, TypeInterpolation interp); + + virtual int getW () { return width; } + virtual int getH () { return height; } + virtual void allocate (int width, int height); + virtual int getBPS () { return 16; } + virtual void getScanline (int row, unsigned char* buffer, int bps); + virtual void setScanline (int row, unsigned char* buffer, int bps); + + // functions inherited from IImage16: + virtual Glib::Mutex& getMutex () { return mutex (); } + virtual cmsHPROFILE getProfile () { return getEmbeddedProfile (); } + virtual int getWidth () { return width; } + virtual int getHeight () { return height; } + virtual int getBitsPerPixel () { return 16; } + 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) { return setProgressListener (pl); } + virtual void free () { delete this; } + virtual unsigned short** getRPlane () { return r; } + virtual unsigned short** getGPlane () { return g; } + virtual unsigned short** getBPlane () { return b; } + + void ExecCMSTransform(cmsHTRANSFORM hTransform); + }; +} +#endif diff --git a/rtengine/image8.cc b/rtengine/image8.cc new file mode 100644 index 000000000..87bfd42df --- /dev/null +++ b/rtengine/image8.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 +#include +#include "image8.h" +#include "rtengine.h" + +using namespace rtengine; + + +Image8::Image8 () + : data(NULL), width(-1), height(-1) { +} + +Image8::Image8 (int w, int h) + : data(NULL), width(w), height (h) { + + allocate (w, h); +} + +void Image8::allocate (int width, int height) { + + if (data!=NULL) + delete [] data; + + data = new unsigned char [width * height * 3]; + this->width = width; + this->height = height; +} + +Image8::~Image8 () { + + if (data!=NULL) + delete [] data; +} + +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; + } +} + +unsigned char Image8::r (int row, int col) { + + return data[3*(row*width+col)]; +} + +unsigned char Image8::g (int row, int col) { + + return data[3*(row*width+col)+1]; +} + +unsigned char Image8::b (int row, int col) { + + return data[3*(row*width+col)+2]; +} + +void Image8::r (int row, int col, unsigned char val) { + + data[3*(row*width+col)] = val; +} + +void Image8::g (int row, int col, unsigned char val) { + + data[3*(row*width+col)+1] = val; +} + +void Image8::b (int row, int col, unsigned char val) { + + data[3*(row*width+col)+2] = val; +} + diff --git a/rtengine/image8.h b/rtengine/image8.h new file mode 100644 index 000000000..42d91d905 --- /dev/null +++ b/rtengine/image8.h @@ -0,0 +1,71 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +// +// A class representing a 8 bit rgb image without alpha channel +// +#ifndef _IMAGE8_ +#define _IMAGE8_ + +#include "imageio.h" +#include "rtengine.h" + +namespace rtengine { + +class Image8 : public ImageIO, public IImage8 { + + public: + unsigned char* data; + int width; + int height; + + Image8 (); + Image8 (int width, int height); + ~Image8 (); + + unsigned char r (int row, int col); + unsigned char g (int row, int col); + unsigned char b (int row, int col); + void r (int row, int col, unsigned char val); + void g (int row, int col, unsigned char val); + void b (int row, int col, unsigned char val); + + virtual int getW () { return width; } + virtual int getH () { return height; } + virtual void allocate (int width, int height); + virtual int getBPS () { return 8; } + virtual void getScanline (int row, unsigned char* buffer, int bps); + virtual void setScanline (int row, unsigned char* buffer, int bps); + + // functions inherited from IImage*: + virtual Glib::Mutex& getMutex () { return mutex (); } + virtual cmsHPROFILE getProfile () { return getEmbeddedProfile (); } + virtual int getWidth () { return width; } + virtual int getHeight () { return height; } + virtual int getBitsPerPixel () { return 16; } + 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 const unsigned char* getData () { return data; } + +}; +} +#endif diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc new file mode 100644 index 000000000..2a8419494 --- /dev/null +++ b/rtengine/imagedata.cc @@ -0,0 +1,451 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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 (exif->getTag ("MakerNote")) { + rtexif::TagDirectory* mnote = exif->getTag ("MakerNote")->getDirectory(); + if (mnote && !make.compare (0, 5, "NIKON")) { + 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; + } + } + 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"); + if ( lt ) { + std::string ldata = lt->valueToString (); + if (ldata.size()>1) { + found=true; + lens = "Canon " + ldata; + } + } + if( !found ){ + 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 (); + } + 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 (); + } 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/imagefloat.cc b/rtengine/imagefloat.cc new file mode 100644 index 000000000..120cceae0 --- /dev/null +++ b/rtengine/imagefloat.cc @@ -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 . + */ +#include "imagefloat.h" +#include "image16.h" +#include "image8.h" +#include +#include "rtengine.h" +#include "mytime.h" +#include "iccstore.h" +#include "alignedbuffer.h" + +using namespace rtengine; + +Imagefloat::Imagefloat () + : unaligned (NULL), data (NULL), r (NULL), g (NULL), b (NULL){ +} + +Imagefloat::Imagefloat (int w, int h) + : unaligned (NULL), width(w), height (h), data (NULL), r (NULL), g (NULL), b (NULL) { + + allocate (w, h); +} + +Imagefloat::~Imagefloat () { + + if (data!=NULL) { + delete [] data; + delete [] r; + delete [] g; + delete [] b; + } +} + +void Imagefloat::allocate (int W, int H) { + + width=W; + height=H; + + if (data!=NULL) { + delete [] data; + delete [] r; + delete [] g; + delete [] b; + } + + /* + int lsize = width + 8 - width % 8; + unaligned = new unsigned char[16 + 3 * lsize * sizeof(float) * height]; + memset(unaligned, 0, (16 + 3 * lsize * sizeof(float) * height) * sizeof(unsigned char)); + + uintptr_t poin = (uintptr_t)unaligned + 16 - (uintptr_t)unaligned % 16; + data = (float*) (poin); + */ + r = new float*[height]; + g = new float*[height]; + b = new float*[height]; + + data = new float[W*H*3]; + rowstride = W; + planestride = rowstride * H; + + float * redstart = data + 0*planestride; + float * greenstart = data + 1*planestride; + float * bluestart = data + 2*planestride; + + + for (int i=0; ir[i], r[i], width*sizeof(float)); + memcpy (cp->g[i], g[i], width*sizeof(float)); + memcpy (cp->b[i], b[i], width*sizeof(float)); + } + + return cp; +} + +Imagefloat* Imagefloat::rotate (int deg) { + + if (deg==90) { + Imagefloat* result = new Imagefloat (height, width); + for (int i=0; ir[i][j] = r[height-1-j][i]; + result->g[i][j] = g[height-1-j][i]; + result->b[i][j] = b[height-1-j][i]; + } + return result; + } + else if (deg==270) { + Imagefloat* result = new Imagefloat (height, width); + for (int i=0; ir[i][j] = r[j][width-1-i]; + result->g[i][j] = g[j][width-1-i]; + result->b[i][j] = b[j][width-1-i]; + } + return result; + } + else if (deg==180) { + Imagefloat* result = new Imagefloat (width, height); + for (int i=0; ir[i][j] = r[height-1-i][width-1-j]; + result->g[i][j] = g[height-1-i][width-1-j]; + result->b[i][j] = b[height-1-i][width-1-j]; + } + return result; + } + else + return NULL; +} + +Imagefloat* Imagefloat::hflip () { + + Imagefloat* result = new Imagefloat (width, height); + for (int i=0; ir[i][j] = r[i][width-1-j]; + result->g[i][j] = g[i][width-1-j]; + result->b[i][j] = b[i][width-1-j]; + } + return result; + +} + +Imagefloat* Imagefloat::vflip () { + + Imagefloat* result = new Imagefloat (width, height); + for (int i=0; ir[i][j] = r[height-1-i][j]; + result->g[i][j] = g[height-1-i][j]; + result->b[i][j] = b[height-1-i][j]; + } + return result; + +} + +/*Imagefloat* Imagefloat::resize (int nw, int nh, TypeInterpolation interp) { + + if (interp == TI_Nearest) { + Imagefloat* res = new Imagefloat (nw, nh); + for (int i=0; ir[i][j] = r[ri][ci]; + res->g[i][j] = g[ri][ci]; + res->b[i][j] = b[ri][ci]; + } + } + return res; + } + else if (interp == TI_Bilinear) { + Imagefloat* res = new Imagefloat (nw, nh); + for (int i=0; i=height) sy = height-1; + double dy = (double)i*height/nh - sy; + int ny = sy+1; + if (ny>=height) ny = sy; + for (int j=0; j=width) sx = width; + double dx = (double)j*width/nw - sx; + int nx = sx+1; + if (nx>=width) nx = sx; + res->r[i][j] = r[sy][sx]*(1-dx)*(1-dy) + r[sy][nx]*dx*(1-dy) + r[ny][sx]*(1-dx)*dy + r[ny][nx]*dx*dy; + res->g[i][j] = g[sy][sx]*(1-dx)*(1-dy) + g[sy][nx]*dx*(1-dy) + g[ny][sx]*(1-dx)*dy + g[ny][nx]*dx*dy; + res->b[i][j] = b[sy][sx]*(1-dx)*(1-dy) + b[sy][nx]*dx*(1-dy) + b[ny][sx]*(1-dx)*dy + b[ny][nx]*dx*dy; + } + } + return res; + } + return NULL; +}*/ + +Image8* +Imagefloat::to8() const +{ + Image8* img8 = new Image8(width,height); + for ( int h = 0; h < height; ++h ) + { + for ( int w = 0; w < width; ++w ) + { + img8->r(h,w,((int)r[h][w]) >> 8); + img8->g(h,w,((int)g[h][w]) >> 8); + img8->b(h,w,((int)b[h][w]) >> 8); + } + } + return img8; +} + +Image16* +Imagefloat::to16() const +{ + Image16* img16 = new Image16(width,height); + for ( int h = 0; h < height; ++h ) + { + for ( int w = 0; w < width; ++w ) + { + img16->r[h][w] = ((int)r[h][w]) ; + img16->g[h][w] = ((int)g[h][w]) ; + img16->b[h][w] = ((int)b[h][w]) ; + } + } + return img16; +} + + +void Imagefloat::calcCroppedHistogram(const ProcParams ¶ms, float scale, LUTu & hist) { + hist.clear(); + + // Set up factors to calc the lightness + TMatrix wprof = iccStore->workingSpaceMatrix (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); + + /* + * WARNING: this parallelization is not 100% safe. Some of its values + * are underestimated by 1 or 2, but in practical, it doesn't seem to be + * annoying in any way, so i guess we may leave it as is... + * (Hombre) + */ + #pragma omp parallel for + for (int y=y1; y65535) i=65535; + hist[i]++; + } + } +} + +// Parallized transformation; create transform with cmsFLAGS_NOCACHE! +void Imagefloat::ExecCMSTransform(cmsHTRANSFORM hTransform) { + + AlignedBufferMP bufMP(width*3); + + // LittleCMS cannot parallize planar setups + // so build temporary buffers to allow multi processor execution + #pragma omp parallel for + for (int y=0; y* pBuf=bufMP.acquire(); + + float *p=pBuf->data, *pR=r[y], *pG=g[y], *pB=b[y]; + + for (int x=0; xdata, pBuf->data, width); + + p=pBuf->data; pR=r[y]; pG=g[y]; pB=b[y]; + for (int x=0; x + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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; +//enum TypeInterpolation { TI_Nearest, TI_Bilinear }; + +class Image8; +class Image16; + +class Imagefloat : public ImageIO, public IImagefloat { + + private: + unsigned char* unaligned; + + public: + int rowstride; + int planestride; + + int width; + int height; + + float* data; + + float** r; + float** g; + float** b; + + + Imagefloat (); + Imagefloat (int width, int height); + ~Imagefloat (); + + Imagefloat* copy (); + + Image8* to8() const; + Image16* to16() const; + + + Imagefloat* rotate (int deg); + Imagefloat* hflip (); + Imagefloat* vflip (); + //Imagefloat* resize (int nw, int nh, TypeInterpolation interp); + + virtual int getW () { return width; } + virtual int getH () { return height; } + virtual void allocate (int width, int height); + 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); + + // functions inherited from IImagefloat: + virtual int getWidth () { return width; } + virtual int getHeight () { return height; } + virtual Glib::Mutex& getMutex () { return mutex (); } + virtual cmsHPROFILE getProfile () { return getEmbeddedProfile (); } + virtual int getBitsPerPixel () { return 16; } + 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) { return setProgressListener (pl); } + virtual void free () { delete this; } + virtual float** getRPlane () { return r; } + virtual float** getGPlane () { return g; } + virtual float** getBPlane () { return b; } + + 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..922f70a31 --- /dev/null +++ b/rtengine/imageio.cc @@ -0,0 +1,953 @@ +/* + * 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" + +#ifdef WIN32 +#include +#else +#include +#endif + +#include "imageio.h" +#include "safegtk.h" +#include "iptcpairs.h" +#include "iccjpeg.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::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); + + 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); + + 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::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, sampleformat; + int hasTag = TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bitspersample); + hasTag &= TIFFGetField(in, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel); + if (!hasTag) { + // These are needed + TIFFClose(in); + return IMIO_VARIANTNOTSUPPORTED; + } + + hasTag=TIFFGetField(in, TIFFTAG_SAMPLEFORMAT, &sampleformat); + if (!hasTag) sampleformat=0; + + uint16 photometric; + if (!TIFFGetField(in, TIFFTAG_PHOTOMETRIC, &photometric) || + photometric != PHOTOMETRIC_RGB || samplesperpixel < 3 || (bitspersample!=8 && bitspersample!=16) || sampleformat>2) { + TIFFClose(in); + return IMIO_VARIANTNOTSUPPORTED; + } + + uint16 config; + TIFFGetField(in, TIFFTAG_PLANARCONFIG, &config); + if (config != PLANARCONFIG_CONTIG) { + TIFFClose(in); + return IMIO_VARIANTNOTSUPPORTED; + } + + char* profdata; + if( loadedProfileData ){ + delete [] loadedProfileData; + loadedProfileData = NULL; + } + if (TIFFGetField(in, TIFFTAG_ICCPROFILE, &loadedProfileLength, &profdata)) { + embProfile = cmsOpenProfileFromMem (profdata, loadedProfileLength); + loadedProfileData = new char [loadedProfileLength]; + memcpy (loadedProfileData, profdata, loadedProfileLength); + } + else + embProfile = NULL; + + + allocate (width, height); + + 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); + } + 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) { + + 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 screwy. + + 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()); + + } + + TIFFSetField (out, TIFFTAG_SOFTWARE, "RawTherapee 4"); + 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..bfa884c9b --- /dev/null +++ b/rtengine/imageio.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 _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" + +namespace rtengine { + +class ImageIO { + + protected: + ProgressListener* pl; + cmsHPROFILE embProfile; + char* profileData; + int profileLength; + char* loadedProfileData; + int loadedProfileLength; + procparams::ExifPairs exifChange; + IptcData* iptc; + const rtexif::TagDirectory* exifRoot; + Glib::Mutex imutex; + + public: + static Glib::ustring errorMsg[6]; + + ImageIO () : pl (NULL), embProfile(NULL), profileData(NULL), loadedProfileData(NULL), loadedProfileLength(0), iptc(NULL), exifRoot (NULL) {} + + virtual ~ImageIO (); + + void setProgressListener (ProgressListener* l) { pl = l; } + + virtual int getW () =0; + virtual int getH () =0; + virtual void allocate (int width, int height) =0; + virtual int getBPS () =0; + virtual void getScanline (int row, unsigned char* buffer, int bps) {} + virtual void setScanline (int row, unsigned char* buffer, int bps) {} + + 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); + + 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); + Glib::Mutex& mutex () { return imutex; } +}; + +} +#endif diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h new file mode 100644 index 000000000..a0cdd2782 --- /dev/null +++ b/rtengine/imagesource.h @@ -0,0 +1,129 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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 "rtengine.h" +#include "colortemp.h" +#include +#include "image16.h" +#include "imagefloat.h" +#include "procparams.h" +#include "coord2d.h" +#include +#include "imagedata.h" +#include "LUT.h" + +namespace rtengine { + +using namespace procparams; + +#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 + +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) {} + +}; + +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: + cmsHPROFILE embProfile; + Glib::ustring fileName; + ImageData* idata; + ImageMatrices imatrices; + + public: + ImageSource () : references (1), embProfile(NULL), idata(NULL) {} + + 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 (HRecParams 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, HRecParams 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, RAWParams raw) =0;// DIRTY HACK: this method is derived in rawimagesource and strimagesource, but (...,RAWParams raw) will be used ONLY for raw images + virtual ColorTemp getWB () =0; + virtual ColorTemp getAutoWB () =0; + virtual ColorTemp getSpotWB (std::vector red, std::vector green, std::vector& blue, int tran) =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 + } + + // 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..4550c35fc --- /dev/null +++ b/rtengine/improccoordinator.cc @@ -0,0 +1,747 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#include "improccoordinator.h" +#include "curves.h" +#include "mytime.h" +#include "refreshmap.h" +#include "simpleprocess.h" +#include "../rtgui/ppversion.h" + +namespace rtengine { + +extern const Settings* settings; + +ImProcCoordinator::ImProcCoordinator () + : workimg(NULL), awbComputed(false), ipf(¶ms, true), scale(10), highDetailPreprocessComputed(false), + highDetailRawComputed(false), allocated(false), + + 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), + + vhist16(65536), + lhist16(65536), lhist16Cropped(65536), + histCropped(65536), + + histRed(256), histRedRaw(256), + histGreen(256), histGreenRaw(256), + histBlue(256), histBlueRaw(256), + histLuma(256), + histToneCurve(256), + histLCurve(256), + bcabhist(256), + + 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), + resultValid(false), changeSinceLast(0), updaterRunning(false), destroying(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) { + + mProcessing.lock (); + + int numofphases = 14; + int readyphase = 0; + + 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.ca_autocorrect = false; + 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.hlrecovery.enabled && params.hlrecovery.method!="Color" && imgsrc->IsrgbSourceModified()) + || (!params.hlrecovery.enabled && params.hlrecovery.method=="Color" && imgsrc->IsrgbSourceModified())) + { + + if (settings->verbose) printf("Demosaic %s\n",rp.dmethod.c_str()); + + //TODO - denoise branch - is this code for WB params still necessary? + currWB = ColorTemp (params.wb.temperature, params.wb.green, params.wb.method); + if (params.wb.method=="Camera") + currWB = imgsrc->getWB (); + else if (params.wb.method=="Auto") { + if (!awbComputed) { + autoWB = imgsrc->getAutoWB (); + awbComputed = true; + } + currWB = autoWB; + } + params.wb.temperature = currWB.getTemp (); + params.wb.green = currWB.getGreen (); + + imgsrc->demosaic( rp ); + + if (highDetailNeeded) { + highDetailRawComputed = true; + if (params.hlrecovery.enabled && params.hlrecovery.method=="Color") { + todo |= M_INIT; + } + } + else + highDetailRawComputed = false; + + + LUTu aehist; int aehistcompr; + double clip; + int brightness, contrast, black, hlcompr, hlcomprthresh; + + imgsrc->getAutoExpHistogram (aehist, aehistcompr); + ipf.getAutoExp (aehist, aehistcompr, imgsrc->getDefGain(), clip, params.dirpyrDenoise.expcomp, brightness, contrast, black, hlcompr, hlcomprthresh); + } + + + if (todo & (M_INIT|M_LINDENOISE)) { + Glib::Mutex::Lock lock(minit); // Also used in crop window + + imgsrc->HLRecovery_Global( params.hlrecovery ); // 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.method); + if (params.wb.method=="Camera") + currWB = imgsrc->getWB (); + else if (params.wb.method=="Auto") { + if (!awbComputed) { + autoWB = imgsrc->getAutoWB (); + awbComputed = true; + } + 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); + setScale (scale); + imgsrc->getImage (currWB, tr, orig_prev, pp, params.hlrecovery, params.icm, params.raw); + + //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); + } + ImageMatrices* imatrices = imgsrc->getImageMatrices (); + } + imgsrc->convertColorSpace(orig_prev, params.icm, params.raw); + + ipf.firstAnalysis (orig_prev, ¶ms, vhist16, imgsrc->getGamma()); + } + readyphase++; + + progress ("Rotate / Distortion...",100*readyphase/numofphases); + bool needstransform = ipf.needsTransform(); + // Remove transformation if unneeded + 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, 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); + } + } + + progress ("Exposure curve & CIELAB conversion...",100*readyphase/numofphases); + if ((todo & M_RGBCURVE) || todo==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); + + // if it's just crop we just need the histogram, no image updates + if ( todo!=CROP ) { + ipf.rgbProc (oprevi, oprevl, hltonecurve, shtonecurve, tonecurve, shmap, params.toneCurve.saturation, + rCurve, gCurve, bCurve, customToneCurve1, customToneCurve2, params.toneCurve.expcomp, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh); + } + + // compute L channel histogram + int x1, y1, x2, y2, pos; + params.crop.mapToResized(pW, pH, scale, x1, x2, y1, y2); + + lhist16.clear(); lhist16Cropped.clear(); + for (int x=0; xL[x][y])); + lhist16[pos]++; + + if (y>=y1 && y=x1 && xCopyFrom(oprevl); + + ipf.EPDToneMap(nprevl,0,scale); + + //progress ("Applying Luminance Curve...",100*readyphase/numofphases); + + //ipf.luminanceCurve (nprevl, nprevl, lumacurve); + + //readyphase++; + progress ("Applying Color Boost...",100*readyphase/numofphases); + ipf.chromiLuminanceCurve (nprevl, nprevl, chroma_acurve, chroma_bcurve, satcurve,lhskcurve, lumacurve, utili, autili, butili, ccutili,cclutili); + //ipf.colorCurve (nprevl, nprevl); + ipf.vibrance(nprevl); + readyphase++; + if (scale==1) { + progress ("Denoising luminance impulse...",100*readyphase/numofphases); + ipf.impulsedenoise (nprevl); + readyphase++; + 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) { + progress ("Microcontrast...",100*readyphase/numofphases); + ipf.MLmicrocontrast (nprevl); + readyphase++; + } + if (params.sharpening.enabled) { + progress ("Sharpening...",100*readyphase/numofphases); + + float **buffer = new float*[pH]; + for (int i=0; ihasListener () && cropCall != crops[i] ) + crops[i]->update (todo); // may call ourselves + + progress ("Conversion to RGB...",100*readyphase/numofphases); + if (todo!=CROP) { + previmg->getMutex().lock(); + try + { + ipf.lab2monitorRgb (nprevl, previmg); + delete workimg; + workimg = ipf.lab2rgb (nprevl, 0,0,pW,pH, params.icm.working); + } + catch(char * str) + { + progress ("Error converting file...",0); + previmg->getMutex().unlock(); + mProcessing.unlock (); + return; + } + previmg->getMutex().unlock(); + } + 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, histRedRaw, histGreenRaw, histBlueRaw); + } + + mProcessing.unlock (); +} + + +void ImProcCoordinator::freeAll () { + + if (settings->verbose) printf ("freeall starts %d\n", (int)allocated); + + if (allocated) { + if (orig_prev!=oprevi) + delete oprevi; + delete orig_prev; + delete oprevl; + delete nprevl; + + if (imageListener) { + imageListener->delImage (previmg); + } + else + delete previmg; + + delete workimg; + delete shmap; + + } + allocated = false; +} + +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); + 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(); + for (int i=y1; iL[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) { + + if (imgsrc && imgsrc->isWBProviderReady()) { + if (!awbComputed) { + minit.lock (); + autoWB = imgsrc->getAutoWB (); + minit.unlock (); + awbComputed = true; + } + temp = autoWB.getTemp (); + green = autoWB.getGreen (); + return true; + } + else { + 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) { + + mProcessing.lock (); + 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; + + ColorTemp ret = imgsrc->getSpotWB (red, green, blue, tr); + currWB = ColorTemp (params.wb.temperature, params.wb.green, params.wb.method); + mProcessing.unlock (); + + 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) { + + mProcessing.lock (); + + 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; + + mProcessing.unlock (); +} + + +void ImProcCoordinator::saveInputICCReference (const Glib::ustring& fname) { + + mProcessing.lock (); + + int fW, fH; + imgsrc->getFullSize (fW, fH, 0); + PreviewProps pp (0, 0, fW, fH, 1); + ProcParams ppar = params; + ppar.hlrecovery.enabled = false; + ppar.icm.input = "(none)"; + Imagefloat* im = new Imagefloat (fW, fH); + Image16* im16 = new Image16 (fW, fH); + imgsrc->preprocess( ppar.raw, ppar.lensProf, ppar.coarse ); + imgsrc->demosaic(ppar.raw ); + //imgsrc->getImage (imgsrc->getWB(), 0, im, pp, ppar.hlrecovery, ppar.icm, ppar.raw); + ColorTemp currWB = ColorTemp (params.wb.temperature, params.wb.green, params.wb.method); + if (params.wb.method=="Camera") + currWB = imgsrc->getWB (); + else if (params.wb.method=="Auto") { + if (!awbComputed) { + autoWB = imgsrc->getAutoWB (); + awbComputed = true; + } + currWB = autoWB; + } + params.wb.temperature = currWB.getTemp (); + params.wb.green = currWB.getGreen (); + imgsrc->getImage (currWB, 0, im, pp, ppar.hlrecovery, ppar.icm, ppar.raw); + imgsrc->convertColorSpace(im, ppar.icm, params.raw); + im16 = im->to16(); + im16->saveTIFF (fname,16,true); + //im->saveJPEG (fname, 85); + mProcessing.unlock (); +} + +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..172c52c87 --- /dev/null +++ b/rtengine/improccoordinator.h @@ -0,0 +1,180 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#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" + +namespace rtengine { + +using namespace procparams; + +class Crop; + +// Manages the image processing, espc. of the preview windows +// There is one ImProcCoordinator per edit panel +class ImProcCoordinator : public StagedImageProcessor { + + friend class Crop; + + protected: + Imagefloat *orig_prev; + Imagefloat *oprevi; + LabImage *oprevl; + LabImage *nprevl; + Image8 *previmg; + Image8 *workimg; + + ImageSource* imgsrc; + + SHMap* shmap; + + ColorTemp currWB; + ColorTemp autoWB; + + bool awbComputed; + + ImProcFunctions ipf; + + int scale; + bool highDetailPreprocessComputed; + bool highDetailRawComputed; + bool allocated; + + void freeAll (); + + LUTf hltonecurve; + LUTf shtonecurve; + LUTf tonecurve; + + LUTf lumacurve; + LUTf chroma_acurve; + LUTf chroma_bcurve; + LUTf satcurve; + LUTf lhskcurve; + + LUTu vhist16; + LUTu lhist16,lhist16Cropped; + LUTu histCropped; + + LUTu histRed, histRedRaw; + LUTu histGreen, histGreenRaw; + LUTu histBlue, histBlueRaw; + LUTu histLuma, histToneCurve, histLCurve, bcabhist; + + LUTf rCurve; + LUTf gCurve; + LUTf bCurve; + + ToneCurve customToneCurve1; + ToneCurve customToneCurve2; + + 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; + HistogramListener* hListener; + std::vector sizeListeners; + + std::vector crops; + + bool resultValid; + + Glib::Mutex minit; + + void progress (Glib::ustring str, int pr); + void reallocAll (); + void updateLRGBHistograms (); + void setScale (int prevscale); + void updatePreviewImage (int todo, Crop* cropCall= NULL); + + Glib::Mutex mProcessing; + ProcParams params; + + // members of the updater: + Glib::Thread* thread; + Glib::Mutex updaterThreadStart; + Glib::Mutex 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); + 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 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..3cbe76f39 --- /dev/null +++ b/rtengine/improcfun.cc @@ -0,0 +1,1459 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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" + +#ifdef _OPENMP +#include +#endif + +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 = 0; + +void ImProcFunctions::initCache () { + + 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 / MAXVAL) )); + } + else { + cachef[i] = 327.68*((Color::kappa*i/MAXVAL+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::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; + + 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 (); + } + + //chroma_scale = 1; + + // calculate histogram of the y channel needed for contrast curve calculation in exposure adjustments + +#ifdef _OPENMP + int T = omp_get_max_threads(); +#else + int T = 1; +#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 i=0; i<65536; i++) + for (int j=0; jtoneCurve.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, double expcomp, int hlcompr, int hlcomprthresh) { + + LUTf iGammaLUTf; + Imagefloat *tmpImage = working->copy(); + + 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); + + 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) + } + }; + + + 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); + + int tW = working->width; + int tH = working->height; + double pi = M_PI; + FlatCurve* hCurve; + FlatCurve* sCurve; + FlatCurve* vCurve; + + + float* cossq = new float [8192]; + for (int i=0; i<8192; i++) + cossq[i] = SQR(cos(pi*(float)i/16384.0)); + + FlatCurveType hCurveType = (FlatCurveType)params->hsvequalizer.hcurve.at(0); + FlatCurveType sCurveType = (FlatCurveType)params->hsvequalizer.scurve.at(0); + FlatCurveType vCurveType = (FlatCurveType)params->hsvequalizer.vcurve.at(0); + bool hCurveEnabled = hCurveType > FCT_Linear; + bool sCurveEnabled = sCurveType > FCT_Linear; + bool vCurveEnabled = vCurveType > 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); + + 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); + + 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; + + //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); + for (int i=0; i<65536; i++) { + iGammaLUTf[i] = float(CurveFactory::igamma (double(i)/65535., g, start, slope, mul, add)*65535.); + } + } + +#ifdef _OPENMP +#pragma omp parallel if (multiThread) +{ +#endif + + if (mixchannels) { +#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 (i==100 & j==100) printf("rgbProc input R= %f G= %f B= %f \n",r,g,b); + + float rmix = (r*chMixRR + g*chMixRG + b*chMixRB) / 100.f; + float gmix = (r*chMixGR + g*chMixGG + b*chMixGB) / 100.f; + float bmix = (r*chMixBR + g*chMixBG + b*chMixBB) / 100.f; + + tmpImage->r[i][j] = rmix; + tmpImage->g[i][j] = gmix; + tmpImage->b[i][j] = bmix; + } + } + } + + if (processSH || processLCE) { +#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]; + + double mapval = 1.0 + shmap->map[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])); + tmpImage->r[i][j] = factor*r-sub; + tmpImage->g[i][j] = factor*g-sub; + tmpImage->b[i][j] = factor*b-sub; + } + else { + tmpImage->r[i][j] = factor*r; + tmpImage->g[i][j] = factor*g; + tmpImage->b[i][j] = factor*b; + } + } + } + } + +#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]; + + //TODO: proper treatment of out-of-gamut colors + //float tonefactor = hltonecurve[(0.299f*r+0.587f*g+0.114f*b)]; + float tonefactor=((rr[i][j] = (r*tonefactor); + tmpImage->g[i][j] = (g*tonefactor); + tmpImage->b[i][j] = (b*tonefactor); + } + } + +#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]; + + //shadow tone curve + float Y = (0.299f*r + 0.587f*g + 0.114f*b); + float tonefactor = shtonecurve[Y]; + tmpImage->r[i][j] *= tonefactor; + tmpImage->g[i][j] *= tonefactor; + tmpImage->b[i][j] *= tonefactor; + } + } + +#ifdef _OPENMP +#pragma omp for schedule(dynamic, 5) +#endif + for (int i=0; ir[i][j] = tonecurve[ tmpImage->r[i][j] ]; + tmpImage->g[i][j] = tonecurve[ tmpImage->g[i][j] ]; + tmpImage->b[i][j] = tonecurve[ tmpImage->b[i][j] ]; + } + } + + if (hasToneCurve1) { + if (curveMode==ToneCurveParams::TC_MODE_STD){ // Standard +#ifdef _OPENMP +#pragma omp for schedule(dynamic, 5) +#endif + for (int i=0; i(customToneCurve1); + userToneCurve.Apply(tmpImage->r[i][j], tmpImage->g[i][j], tmpImage->b[i][j]); + } + } + } + else if (curveMode==ToneCurveParams::TC_MODE_FILMLIKE){ // Adobe like +#ifdef _OPENMP +#pragma omp for schedule(dynamic, 5) +#endif + for (int i=0; i(customToneCurve1); + userToneCurve.Apply(tmpImage->r[i][j], tmpImage->g[i][j], tmpImage->b[i][j]); + } + } + } + else if (curveMode==ToneCurveParams::TC_MODE_SATANDVALBLENDING){ // apply the curve on the saturation and value channels +#ifdef _OPENMP +#pragma omp for schedule(dynamic, 5) +#endif + for (int i=0; i(customToneCurve1); + userToneCurve.Apply(tmpImage->r[i][j], tmpImage->g[i][j], tmpImage->b[i][j]); + } + } + } + else if (curveMode==ToneCurveParams::TC_MODE_WEIGHTEDSTD){ // apply the curve to the rgb channels, weighted +#ifdef _OPENMP +#pragma omp for schedule(dynamic, 5) +#endif + for (int i=0; i(customToneCurve1); + userToneCurve.Apply(tmpImage->r[i][j], tmpImage->g[i][j], tmpImage->b[i][j]); + } + } + } + } + + if (hasToneCurve2) { + if (curveMode2==ToneCurveParams::TC_MODE_STD){ // Standard +#ifdef _OPENMP +#pragma omp for schedule(dynamic, 5) +#endif + for (int i=0; i(customToneCurve2); + userToneCurve.Apply(tmpImage->r[i][j], tmpImage->g[i][j], tmpImage->b[i][j]); + } + } + } + else if (curveMode2==ToneCurveParams::TC_MODE_FILMLIKE){ // Adobe like +#ifdef _OPENMP +#pragma omp for schedule(dynamic, 5) +#endif + for (int i=0; i(customToneCurve2); + userToneCurve.Apply(tmpImage->r[i][j], tmpImage->g[i][j], tmpImage->b[i][j]); + } + } + } + else if (curveMode2==ToneCurveParams::TC_MODE_SATANDVALBLENDING){ // apply the curve on the saturation and value channels +#ifdef _OPENMP +#pragma omp for schedule(dynamic, 5) +#endif + for (int i=0; i(customToneCurve2); + userToneCurve.Apply(tmpImage->r[i][j], tmpImage->g[i][j], tmpImage->b[i][j]); + } + } + } + else if (curveMode2==ToneCurveParams::TC_MODE_WEIGHTEDSTD){ // apply the curve to the rgb channels, weighted +#ifdef _OPENMP +#pragma omp for schedule(dynamic, 5) +#endif + for (int i=0; i(customToneCurve2); + userToneCurve.Apply(tmpImage->r[i][j], tmpImage->g[i][j], tmpImage->b[i][j]); + } + } + } + } + + if (iGammaLUTf) { +#ifdef _OPENMP +#pragma omp for schedule(dynamic, 5) +#endif + for (int i=0; ir[i][j] = iGammaLUTf[ tmpImage->r[i][j] ]; + tmpImage->g[i][j] = iGammaLUTf[ tmpImage->g[i][j] ]; + tmpImage->b[i][j] = iGammaLUTf[ tmpImage->b[i][j] ]; + } + } + } + + if (rCurve) { +#ifdef _OPENMP +#pragma omp for schedule(dynamic, 5) +#endif + for (int i=0; ir[i][j] = rCurve[ tmpImage->r[i][j] ]; + } + } + } + + if (gCurve) { +#ifdef _OPENMP +#pragma omp for schedule(dynamic, 5) +#endif + for (int i=0; ig[i][j] = gCurve[ tmpImage->g[i][j] ]; + } + } + } + + if (bCurve) { +#ifdef _OPENMP +#pragma omp for schedule(dynamic, 5) +#endif + for (int i=0; ib[i][j] = bCurve[ tmpImage->b[i][j] ]; + } + } + } + + + if (sat!=0 || hCurveEnabled || sCurveEnabled || vCurveEnabled) { +#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]; + + float h,s,v; + Color::rgb2hsv(r,g,b,h,s,v); + if (sat > 0.5f) { + s = (1.f-float(sat)/100.f)*s+float(sat)/100.f*(1.f-SQR(SQR(1.f-min(s,1.0f)))); + if (s<0) s=0.f; + } else { + if (sat < -0.5) + s *= 1.f+float(sat)/100.f; + } + //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))); + if (v<0) v=0; + } else { + if (valparam < -0.00001f) + v *= (1.f+valparam); + } + + } + Color::hsv2rgb(h, s, v, tmpImage->r[i][j], tmpImage->g[i][j], tmpImage->b[i][j]); + } + } + } + +#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]; + + 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*exp(log(x/MAXVAL)/3.0f ))); + fy = (y<65535.0f ? cachef[std::max(y,0.f)] : (327.68f*exp(log(y/MAXVAL)/3.0f ))); + fz = (z<65535.0f ? cachef[std::max(z,0.f)] : (327.68f*exp(log(z/MAXVAL)/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;*/ + + } + } +#ifdef _OPENMP +} +#endif + + delete tmpImage; + + if (hCurveEnabled) delete hCurve; + if (sCurveEnabled) delete sCurve; + if (vCurveEnabled) delete vCurve; + delete [] cossq; +} + +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 (LabImage* lold, LabImage* lnew, LUTf & acurve, LUTf & bcurve, LUTf & satcurve,LUTf & lhskcurve, LUTf & curve, bool utili, bool autili, bool butili, bool ccutili, bool cclutili) { + + int W = lold->W; + int H = lold->H; + // lhskcurve.dump("lh_curve"); + + //init Flatcurve for C=f(H) + FlatCurve* chCurve = NULL; + bool chutili = false; + if (!params->labCurve.bwtoning) { + chCurve = new FlatCurve(params->labCurve.chcurve); + if (chCurve && !chCurve->isIdentity()) { + chutili=true; + }//do not use "Munsell" if Chcurve not used + } +#ifdef _DEBUG + MyTime t1e,t2e, t3e, t4e; + t1e.set(); + // init variables to display Munsell corrections + MunsellDebugInfo* MunsDebugInfo = new MunsellDebugInfo(); +#endif + + unsigned int N = W*H; + float *L = lold->L[0]; + float *a= lold->a[0]; + float *b= lold->b[0]; + + float* Lold = new float [lold->W*lold->H];//to save L before any used + float* Cold = new float [lold->W*lold->H];//to save C before any used + float adjustr=1.0f, adjustbg=1.0f; + +// if(params->labCurve.avoidclip ){ + for (unsigned int j=0; j!=N; j++){ + Lold[j]=L[j]/327.68f; + Cold[j]=sqrt(SQR(a[j]/327.68f)+SQR(b[j]/327.68f)); +// Hr=atan2(b[j],a[j]); +// if(Hr >-0.15f && Hr < 1.5f && Cold[j]>maxCr) +// maxCr=Cold[j]; // I do not take into account "acurve" and "bcurve" to adjust max +// else if (Cold[j]>maxCbg) +// maxCbg=Cold[j]; + } + // 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->hlrecovery.enabled; //Get the value if "highlight reconstruction" is activated + int chromaticity = params->labCurve.chromaticity; + bool bwToning = params->labCurve.bwtoning; + bool LCredsk = params->labCurve.lcredsk; + bool ccut = ccutili; + double rstprotection = 100.-params->labCurve.rstprotection; // Red and Skin Tones Protection + // avoid color shift is disabled when bwToning is activated + bool avoidColorShift = params->labCurve.avoidcolorshift && !bwToning; + int protectRed = settings->protectred; + double protectRedH = settings->protectredh; + bool gamutLch = settings->gamutLch; + // only if user activate Lab adjustements + if (avoidColorShift) { + if(autili || butili || ccutili || cclutili || chutili || utili || chromaticity) + Color::LabGamutMunsell(lold, Lold, Cold, /*corMunsell*/true, /*lumaMuns*/false, params->hlrecovery.enabled, /*gamut*/true, params->icm.working, multiThread); + } + + +#ifdef _DEBUG +#pragma omp parallel default(shared) firstprivate(highlight, ccut, chromaticity, bwToning, rstprotection, avoidColorShift, LCredsk, protectRed, protectRedH, gamutLch, lold, lnew, MunsDebugInfo) if (multiThread) +#else +#pragma omp parallel default(shared) firstprivate(highlight, ccut, chromaticity, bwToning, rstprotection, avoidColorShift, LCredsk, protectRed, protectRedH, gamutLch, lold, lnew) 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, 10) + for (int i=0; iL[i][j]/327.68f; + float CC=sqrt(SQR(lold->a[i][j]/327.68f) + SQR(lold->b[i][j]/327.68f)); + float HH=atan2(lold->b[i][j],lold->a[i][j]); + float Chprov=CC; + float Chprov1=CC; + float memChprov=Chprov; + float Lprov2=LL; + float Lin=lold->L[i][j]; + 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 +// calculate C=f(H) + if (chutili) { + double hr; + //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 !!) + if (HH<-2.7f) hr=0.020380804*double(HH)+0.970281708; //Lab green =>hr # 0.33 ==> 0.33 0.42 + else if (HH<-2.1f) hr=0.266666667*double(HH)+1.14; //Lab cyan =>hr # 0.50 ==> 0.42 0.58 + else if (HH<-0.9f) hr=0.141666 *double(HH)+0.8775; //Lab blue =>hr # 0.67 ==> 0.58 0.75 + else if (HH<-0.1f) hr=0.2125 *double(HH)+0.94125; //Lab magenta (purple) =>hr # 0.83 ==> 0.75 0.92 + else if (HH< 1.3f) hr=0.12142857 *double(HH)+0.932142857; //Lab red and skin =>hr # 0 ==> 0.92 1.09 + else if (HH< 2.2f) hr=0.1666667 *double(HH)-0.1266667; //Lab yellow and green yellow =>hr # 0.16 ==> 0.09 0.24 + else hr=0.0955828 *double(HH)+0.02971784; //Lab green =>hr # 0.33 ==> 0.24 0.33 + + //allways put h between 0 and 1 + if (hr<0.0) hr += 1.0; + else if(hr>1.0) hr -= 1.0; + float chparam = float((chCurve->getVal(hr)-0.5f) * 2.0f);//get C=f(H) + chromaChfactor=1.0f+chparam; + } + atmp *= chromaChfactor;//apply C=f(H) + btmp *= chromaChfactor; + //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(chromaticity!=0 && !bwToning){ + + 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; + factor=factorsat; + + 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; + } + + // 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) + + 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=20.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 + } + + 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; + lnew->a[i][j]=327.68f*Chprov1*cos(HH); + lnew->b[i][j]=327.68f*Chprov1*sin(HH); + } + 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 || cclutili || chutili || 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. + */ + lnew->a[i][j]=327.68f*Chprov*cos(HH+correctionHue);// apply Munsell + lnew->b[i][j]=327.68f*Chprov*sin(HH+correctionHue); + } + } + else { +// if(Lprov1 > maxlp) maxlp=Lprov1; +// if(Lprov1 < minlp) minlp=Lprov1; + lnew->L[i][j]=Lprov1*327.68f; + + //Luv limiter only + lnew->a[i][j] = atmp; + lnew->b[i][j] = btmp; + } + } +} // end of parallelization + +#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 + delete [] Lold; + delete [] Cold; + + if (chutili) delete chCurve; +} + + +//#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::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::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); + + } + } + +//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; + + //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; + for(i = 0; i != N; i++) + if(L[i] < minL) minL = L[i]; + 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. + + for(i = 0; i != N; i++) + L[i] = (L[i] - minL)/32767.0f; + + //Some interpretations. + float Compression = expf(-p->Strength); //This modification turns numbers symmetric around 0 into exponents. + float DetailBoost = p->Strength; + if(p->Strength < 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)(p->EdgeStopping*15.0); + +/* 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, (float)p->Scale/skip, (float)p->EdgeStopping, Compression, DetailBoost, Iterates, p->ReweightingIterates, 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)); + for(i = 0; i != N; i++) + a[i] *= s, + b[i] *= s, + L[i] = L[i]*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.0; + float midgray=0.15;//0.18445f;//middle gray in linear gamma = 0.18445*65535 + + int imax=65536>>histcompr; + + float sum = 0, hisum=0, losum=0; + float ave = 0, hidev=0, lodev=0; + //find average luminance + for (int i=0; isum/8 || (count==7 && octile[count]>sum/16)) { + octile[count]=log(1+i)/log(2); + count++;// = min(count+1,7); + } + } + if (ilog(imax+1)/log2(2)) { + octile[7]=1.5*octile[6]-0.5*octile[5]; + } + for(int i=1; i<8; i++) { + if (octile[i] == 0.0) + 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; + if (ospread<=0) {//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 ); + clipped = 0; + int whiteclip = (imax) - 1; + while (whiteclip>1 && histogram[whiteclip]+clipped <= clippable) { + clipped += histogram[whiteclip]; + whiteclip--; + } + + //compute clipped black point + clipped = 0; + int shc = 0; + while (shc>histcompr; i++) + gavg += histogram[i] * CurveFactory::gamma2((int)(corr*(i<10.0) expcomp = 10.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, 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; + } + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +} diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h new file mode 100644 index 000000000..d81643af1 --- /dev/null +++ b/rtengine/improcfun.h @@ -0,0 +1,162 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#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 "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, const LCPMapper *pLCPMap); + void transformVignetteOnly (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int oW, int oH); + void transformHighQuality (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, const LCPMapper *pLCPMap, bool fullImage); + + void sharpenHaloCtrl (LabImage* lab, 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 needsVignetting (); + bool needsLCP (); + // static cmsUInt8Number* Mempro = NULL; + + + public: + bool iGamma; // true if inverse gamma has to be applied in rgbProc + double g; + + static LUTf cachef; + + double lumimul[3]; + + static void initCache (); + static void cleanupCache (); + + ImProcFunctions (const ProcParams* iparams, bool imultiThread=true) + : monitorTransform(NULL), params(iparams), scale(1), multiThread(imultiThread), iGamma(true), g(0.0) {} + ~ImProcFunctions (); + + void setScale (double iscale); + + bool needsTransform (); + + void firstAnalysis (Imagefloat* working, const ProcParams* params, LUTu & vhist16, double gamma); + void 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); + void 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, + double expcomp, int hlcompr, int hlcomprthresh); + void luminanceCurve (LabImage* lold, LabImage* lnew, LUTf &curve); + + void chromiLuminanceCurve (LabImage* lold, LabImage* lnew, LUTf &acurve, LUTf &bcurve, LUTf & satcurve,LUTf & satclcurve, LUTf &curve, bool utili, bool autili, bool butili, bool ccutili, bool cclutili); + void vibrance (LabImage* lab);//Jacques' vibrance + void colorCurve (LabImage* lold, LabImage* lnew); + void sharpening (LabImage* lab, float** buffer); + void transform (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, + double focalLen, double focalLen35mm, float focusDist, int rawRotationDeg, bool fullImage); + void lab2monitorRgb (LabImage* lab, Image8* image); + void resize (Image16* src, Image16* dst, float dScale); + void deconvsharpening (LabImage* lab, float** buffer); + void MLsharpen (LabImage* lab);// Manuel's clarity / sharpening + void MLmicrocontrast(LabImage* lab ); //Manuel's microcontrast + + void impulsedenoise (LabImage* lab);//Emil's impulse denoise + void impulse_nr (LabImage* lab, double thresh); + void dirpyrdenoise (LabImage* src);//Emil's pyramid denoise + void dirpyrequalizer (LabImage* lab);//Emil's equalizer + + void EPDToneMap(LabImage *lab, unsigned int Iterates = 0, int skip = 1); + + // pyramid denoise + procparams::DirPyrDenoiseParams dnparams; + void dirpyrLab_denoise(LabImage * src, LabImage * dst, const procparams::DirPyrDenoiseParams & dnparams );//Emil's directional pyramid denoise + void dirpyr (LabImage* data_fine, LabImage* data_coarse, int level, LUTf &rangefn_L, LUTf &rangefn_ab, + int pitch, int scale, const int luma, int chroma ); + void 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*/ ); + + // FT denoise + //void RGB_InputTransf(Imagefloat * src, LabImage * dst, const procparams::DirPyrDenoiseParams & dnparams, const procparams::DefringeParams & defringe); + //void RGB_OutputTransf(LabImage * src, Imagefloat * dst, const procparams::DirPyrDenoiseParams & dnparams); + //void output_tile_row (float *Lbloxrow, float ** Lhipassdn, float ** tilemask, int height, int width, int top, int blkrad ); + void RGB_denoise(Imagefloat * src, Imagefloat * dst, bool isRAW, const procparams::DirPyrDenoiseParams & dnparams, const procparams::DefringeParams & defringe); + void RGBtile_denoise (float * fLblox, int vblproc, int hblproc, int numblox_H, int numblox_W, float noisevar_L ); //for DCT + void RGBoutput_tile_row (float *Lbloxrow, float ** Ldetail, float ** tilemask_out, int height, int width, int top ); + //void WaveletDenoise(cplx_wavelet_decomposition &DualTreeCoeffs, float noisevar ); + //void WaveletDenoise(wavelet_decomposition &WaveletCoeffs, float noisevar ); + void WaveletDenoiseAll(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_a, + wavelet_decomposition &WaveletCoeffs_b, float noisevar_L, float noisevar_ab ); + void WaveletDenoiseAll_BiShrink(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_a, + wavelet_decomposition &WaveletCoeffs_b, float noisevar_L, float noisevar_ab ); + //void BiShrink(float * ReCoeffs, float * ImCoeffs, float * ReParents, float * ImParents, + // int W, int H, int level, int padding, float noisevar); + //void Shrink(float ** WavCoeffs, int W, int H, int level, float noisevar); + void ShrinkAll(float ** WavCoeffs_L, float ** WavCoeffs_a, float ** WavCoeffs_b, int level, + int W_L, int H_L, int W_ab, int H_ab, int skip_L, int skip_ab, float noisevar_L, float noisevar_ab); + float MadMax(float * HH_Coeffs, int &max, int datalen); + + // pyramid equalizer + void dirpyr_equalizer (float ** src, float ** dst, int srcwidth, int srcheight, const double * mult );//Emil's directional pyramid equalizer + void dirpyr_channel (float ** data_fine, float ** data_coarse, int width, int height, LUTf & rangefn, int level, int scale, const double * mult ); + void idirpyr_eq_channel (float ** data_coarse, float ** data_fine, float ** buffer, int width, int height, int level, const double * mult ); + + void defringe (LabImage* lab); + void PF_correct_RT (LabImage * src, LabImage * dst, double radius, int thresh); + + Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile); + Image16* 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);// for gamma output + Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile);//without gamma ==>default + + 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); + 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..0ae7e5b58 --- /dev/null +++ b/rtengine/impulse_denoise.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 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 "rt_math.h" +#include "labimage.h" +#include "improcfun.h" + +using namespace std; + +namespace rtengine { + +void ImProcFunctions::impulse_nr (LabImage* lab, double thresh) { + + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // impulse noise removal + // local variables + + int width = lab->W; + int height = lab->H; + + float hpfabs, hfnbrave; + + // 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); + + for (int i=0; i < height; i++) + for (int j=0; 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=max(0,j-2); j1<=min(j+2,width-1); j1++ ) { + hfnbrave += fabs(lab->L[i1][j1]-lpf[i1][j1]); + } + hfnbrave = (hfnbrave-hpfabs)/24; + hpfabs>(hfnbrave*impthr) ? impish[i][j]=1 : impish[i][j]=0; + + }//now impulsive values have been identified + + for (int i=0; i < height; i++) + for (int j=0; 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), hfnbrave=0; i1<=min(i+2,height-1); i1++ ) + for (j1=max(0,j-2); j1<=min(j+2,width-1); 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; + } + //wtdsum /= norm; + 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; 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 "improcfun.h" +#include "improccoordinator.h" +#include "dfmanager.h" +#include "ffmanager.h" +#include "rtthumbnail.h" +#include "../rtgui/profilestore.h" + +namespace rtengine { + +const Settings* settings; + +Glib::Mutex* lcmsMutex = NULL; + +int init (const Settings* s, Glib::ustring baseDir) { + + settings = s; + iccStore->init (s->iccDirectory, baseDir + "/iccprofiles"); + iccStore->findDefaultMonitorProfile(); + + dcpStore->init (baseDir + "/dcpprofiles"); + + profileStore.init (); + ProcParams::init (); + Color::init(); + ImProcFunctions::initCache (); + Thumbnail::initGamma (); + delete lcmsMutex; + lcmsMutex = new Glib::Mutex; + dfm.init( s->darkFramesPath ); + ffm.init( s->flatFieldsPath ); + return 0; +} + +void cleanup () { + + ProcParams::cleanup (); + Color::cleanup (); + ImProcFunctions::cleanupCache (); + Thumbnail::cleanupGamma (); +} + +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..f0025a26b --- /dev/null +++ b/rtengine/iplab2rgb.cc @@ -0,0 +1,457 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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) { + AlignedBufferMP bufferMP(3*lab->W); + + // cmsDoTransform is relatively expensive + #pragma omp parallel for + for (int i=0; iH; i++) { + // pre-conversion to integer, since the output is 8 bit anyway, but LCMS is MUCH faster not converting from float + AlignedBuffer* pBuf=bufferMP.acquire(); + unsigned short * buffer=pBuf->data; + + const int ix = i * 3 * lab->W; + int iy = 0; + + float* rL = lab->L[i]; + float* ra = lab->a[i]; + float* rb = lab->b[i]; + + float fy,fx,fz,x_,y_,z_,LL; + + for (int j=0; jW; j++) { + + fy = (0.00862069 * rL[j]) / 327.68 + 0.137932; // (L+16)/116 + fx = (0.002 * ra[j]) / 327.68 + fy; + fz = fy - (0.005 * rb[j]) / 327.68; + LL=rL[j]/327.68; + x_ = Color::f2xyz(fx)*Color::D50x; + //y_ = Color::f2xyz(fy); + y_= (LL>Color::epskap) ? fy*fy*fy : LL/Color::kappa; + + z_ = Color::f2xyz(fz)*Color::D50z; + + buffer[iy++] = (unsigned short)CLIP(x_* MAXVAL+0.5); + buffer[iy++] = (unsigned short)CLIP(y_* MAXVAL+0.5); + buffer[iy++] = (unsigned short)CLIP(z_* MAXVAL+0.5); + } + + cmsDoTransform (monitorTransform, buffer, image->data + ix, lab->W); + + bufferMP.release(pBuf); + } + + } else { + + #pragma omp parallel for if (multiThread) + for (int i=0; iH; i++) { + float* rL = lab->L[i]; + float* ra = lab->a[i]; + float* rb = lab->b[i]; + int ix = i * 3 * lab->W; + + float R,G,B; + float fy,fx,fz,x_,y_,z_,LL; + + for (int j=0; jW; j++) { + + //float L1=rL[j],a1=ra[j],b1=rb[j];//for testing + + fy = (0.00862069 * rL[j]) / 327.68 + 0.137932; // (L+16)/116 + fx = (0.002 * ra[j]) / 327.68 + fy; + fz = fy - (0.005 * rb[j]) / 327.68; + LL=rL[j]/327.68; + + x_ = 65535.0 * Color::f2xyz(fx)*Color::D50x; + // y_ = 65535.0 * Color::f2xyz(fy); + z_ = 65535.0 * Color::f2xyz(fz)*Color::D50z; + y_= (LL>Color::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)]) + image->data[ix++] = ((int)gamma2curve[CLIP(R)]) >> 8; + image->data[ix++] = ((int)gamma2curve[CLIP(G)]) >> 8; + image->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) { + + //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 iprof = iccStore->getXYZProfile (); + lcmsMutex->lock (); + cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprof, TYPE_RGB_8, settings->colorimetricIntent, + cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is important for thread safety + lcmsMutex->unlock (); + + // cmsDoTransform is relatively expensive + #pragma omp parallel for + 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, image->data + ix, cw); + } + + cmsDeleteTransform(hTransform); + } 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); + 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 + 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); + 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..7263ba53a --- /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 horisontal 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..f71c8e3be --- /dev/null +++ b/rtengine/ipsharpen.cc @@ -0,0 +1,621 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#include "rtengine.h" +#include "improcfun.h" +#include "gauss.h" +#include "bilateral2.h" +#include "rt_math.h" + +#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; + +void ImProcFunctions::dcdamping (float** aI, float** aO, float damping, int W, int H) { + + const float dampingFac=2.0/(damping*damping); + +#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; + 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.0) + contrast=1.0; + + // new possible values + if (((L[offset]L[offset+1])) || ((L[offset]>L[offset-1])&&(L[offset]L[offset+width])) || ((L[offset]>L[offset-width])&&(L[offset]L[offset+1+width])) || ((L[offset]>L[offset-1-width])&&(L[offset]L[offset-1+width])) || ((L[offset]>L[offset+1-width])&&(L[offset]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; + templab = v*(1-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/ +// addition from JD : pyramid + pondered contrast with matrix 5x5 +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)); + +} + +} 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..3db0451bb --- /dev/null +++ b/rtengine/iptransform.cc @@ -0,0 +1,596 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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)<1e-3 ? 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)<1e-3 ? 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, + 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()) + transformVignetteOnly (original, transformed, cx, cy, oW, oH); + else if (!needsCA() && scale!=1) + transformPreview (original, transformed, cx, cy, sx, sy, oW, oH, pLCPMap); + else + transformHighQuality (original, transformed, cx, cy, sx, sy, oW, oH, 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); +} + +// Transform vignetting only +void ImProcFunctions::transformVignetteOnly (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int oW, int oH) { + + double vig_w2, vig_h2, maxRadius, v, b, mul; + calcVignettingParams(oW, oH, params->vignetting, vig_w2, vig_h2, maxRadius, v, b, mul); + + #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 vign = std::max(v + mul * tanh (b*(maxRadius-r) / maxRadius), 0.001); + transformed->r[y][x] = original->r[y][x] / vign; + transformed->g[y][x] = original->g[y][x] / vign; + transformed->b[y][x] = original->b[y][x] / vign; + } + } +} + +// Transform WITH scaling (opt.) and CA, cubic interpolation +#include "cubintch.cc" +#include "cubint.cc" + +void ImProcFunctions::transformHighQuality (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, + 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); + + float** chOrig[3]; + chOrig[0] = original->r; + chOrig[1] = original->g; + chOrig[2] = original->b; + + float** chTrans[3]; + chTrans[0] = transformed->r; + chTrans[1] = transformed->g; + chTrans[2] = transformed->b; + + // 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)<1e-3 ? 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)<1e-3 ? 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 (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, 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); + + // 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)<1e-3 ? 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)<1e-3 ? 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 (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::needsVignetting () { + return params->vignetting.amount; +} + +bool ImProcFunctions::needsLCP () { + return params->lensProf.lcpFile.length()>0; +} + +bool ImProcFunctions::needsTransform () { + return needsCA () || needsDistortion () || needsRotation () || needsPerspective () || needsVignetting () || needsLCP(); +} + + +} + diff --git a/rtengine/ipvibrance.cc b/rtengine/ipvibrance.cc new file mode 100644 index 000000000..a52a0cfcf --- /dev/null +++ b/rtengine/ipvibrance.cc @@ -0,0 +1,468 @@ +/* + * 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, int skip, bool needed) { + if (needed && diagCurve) { + LUTf lutCurve (65536); + + for (int i=0; i<=0xffff; i+= i<0xffff-skip ? skip : 1 ) { + // change to [0,1] range + // apply custom/parametric/NURBS curve, if any + // and store result in a temporary array + lutCurve[i] = diagCurve->getVal( double(i)/65535.0 ); + } + + // 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++) { + int iMod = i%skip; + if (!iMod) { + prev+=skip; + continue; + } + lutCurve[i] = ( lutCurve[prev] * (skip-iMod) + lutCurve[prev+skip]*iMod ) / skip; + } + } + + for (int i=0; i<=0xffff; i++) { + outCurve[i] = (65535.0f * lutCurve[i]); + } + } + 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) { + + int skip=1; //scale==1 ? 1 : 16; + bool skinCurveIsSet=false; + DiagonalCurve* dcurve = NULL; + dcurve = new DiagonalCurve (params->vibrance.skintonescurve, CURVES_MIN_POLY_POINTS/skip); + if (dcurve) { + if (!dcurve->isIdentity()) { + skinCurveIsSet = true; + } + else { + delete dcurve; + dcurve = NULL; + } + } + + if (!params->vibrance.enabled || (!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); + + fillCurveArrayVib(dcurve, skin_curve, skip, 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->hlrecovery.enabled;//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=atan2(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 + } + aprovn=Chprov*cos(HH+correctionHue); + bprovn=Chprov*sin(HH+correctionHue); + + 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..7389e0fbc --- /dev/null +++ b/rtengine/labimage.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 _LABIMAGE_H_ +#define _LABIMAGE_H_ + +#include "image16.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..3982675bf --- /dev/null +++ b/rtengine/lcp.cc @@ -0,0 +1,679 @@ +/* +* 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=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 parameters\n"); +} + +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 (!pProf->inCamProfiles || pProf->inAlternateLensID) 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->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 (!pProf->inCamProfiles || pProf->inAlternateLensID) 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 Glib::Mutex smutex_; + Glib::Mutex::Lock lock(smutex_); + if ( instance_ == 0 ) + { + instance_ = new LCPStore(); + } + } + return instance_; +} + +LCPProfile* LCPStore::getProfile (Glib::ustring filename) { + if (filename.length()==0 || !isValidLCPFileName(filename)) return NULL; + + Glib::Mutex::Lock 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; +} \ No newline at end of file diff --git a/rtengine/lcp.h b/rtengine/lcp.h new file mode 100644 index 000000000..71d71c3e5 --- /dev/null +++ b/rtengine/lcp.h @@ -0,0 +1,131 @@ +/* +* 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 +#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; + 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 { + Glib::Mutex 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 100644 index 000000000..9b3b5a10a --- /dev/null +++ b/rtengine/myfile.cc @@ -0,0 +1,353 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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 + +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; +} + +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 == 0 ) + { + 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/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..931d45bd4 --- /dev/null +++ b/rtengine/procevents.h @@ -0,0 +1,202 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#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, + EvPrefProfile=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, + EvHRMethod=67, + EvWProfile=68, + EvOProfile=69, + EvIProfile=70, + EvVignetting=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, + EvEqlEnabled=85,// obsolete + 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, + 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, + EvLCCCurve=167, + EvLCHCurve=168, + EvVibranceSkinTonesCurve=169, + EvLLCCurve=170, + EvLLCredsk=171, + EvDPDNLdetail=172, + + NUMOFEVENTS=173 +}; +} +#endif diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc new file mode 100644 index 000000000..de3b0abb1 --- /dev/null +++ b/rtengine/procparams.cc @@ -0,0 +1,1553 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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]={"eahd", "hphd", "vng4", "dcb", "amaze", "ahd", "fast" }; +const char *RAWParams::ff_BlurTypestring[RAWParams::numFlatFileBlurTypes]={/*"Parametric",*/ "Area Flatfield", "Vertical Flatfield", "Horizontal Flatfield", "V+H Flatfield"}; +std::vector WBParams::wbEntries; + +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)); + wbEntries.push_back(new WBEntry("Auto" ,WBT_AUTO, M("TP_WBALANCE_AUTO"), 0)); + wbEntries.push_back(new WBEntry("Daylight" ,WBT_DAYLIGHT, M("TP_WBALANCE_DAYLIGHT"), 5300)); + wbEntries.push_back(new WBEntry("Cloudy" ,WBT_CLOUDY, M("TP_WBALANCE_CLOUDY"), 6200)); + wbEntries.push_back(new WBEntry("Shade" ,WBT_SHADE, M("TP_WBALANCE_SHADE"), 7600)); + wbEntries.push_back(new WBEntry("Tungsten" ,WBT_TUNGSTEN, M("TP_WBALANCE_TUNGSTEN"), 2856)); + wbEntries.push_back(new WBEntry("Fluo F1" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO1"), 6430)); + wbEntries.push_back(new WBEntry("Fluo F2" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO2"), 4230)); + wbEntries.push_back(new WBEntry("Fluo F3" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO3"), 3450)); + wbEntries.push_back(new WBEntry("Fluo F4" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO4"), 2940)); + wbEntries.push_back(new WBEntry("Fluo F5" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO5"), 6350)); + wbEntries.push_back(new WBEntry("Fluo F6" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO6"), 4150)); + wbEntries.push_back(new WBEntry("Fluo F7" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO7"), 6500)); + wbEntries.push_back(new WBEntry("Fluo F8" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO8"), 5020)); + wbEntries.push_back(new WBEntry("Fluo F9" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO9"), 4330)); + wbEntries.push_back(new WBEntry("Fluo F10" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO10"), 5300)); + wbEntries.push_back(new WBEntry("Fluo F11" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO11"), 4000)); + wbEntries.push_back(new WBEntry("Fluo F12" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO12"), 3000)); + wbEntries.push_back(new WBEntry("HMI Lamp" ,WBT_LAMP, M("TP_WBALANCE_HMI"), 4800)); + wbEntries.push_back(new WBEntry("GTI Lamp" ,WBT_LAMP, M("TP_WBALANCE_GTI"), 5000)); + wbEntries.push_back(new WBEntry("JudgeIII Lamp" ,WBT_LAMP, M("TP_WBALANCE_JUDGEIII"), 5100)); + wbEntries.push_back(new WBEntry("Solux Lamp 3500K" ,WBT_LAMP, M("TP_WBALANCE_SOLUX35"), 3480)); + wbEntries.push_back(new WBEntry("Solux Lamp 4100K" ,WBT_LAMP, M("TP_WBALANCE_SOLUX41"), 3930)); + wbEntries.push_back(new WBEntry("Solux Lamp 4700K" ,WBT_LAMP, M("TP_WBALANCE_SOLUX47"), 4700)); + wbEntries.push_back(new WBEntry("NG Solux Lamp 4700K" ,WBT_LAMP, M("TP_WBALANCE_SOLUX47_NG"), 4480)); + wbEntries.push_back(new WBEntry("LED LSI Lumelex 2040",WBT_LED, M("TP_WBALANCE_LED_LSI"), 3000)); + wbEntries.push_back(new WBEntry("LED CRS SP12 WWMR16" ,WBT_LED, M("TP_WBALANCE_LED_CRS"), 3050)); + wbEntries.push_back(new WBEntry("Flash 5500K" ,WBT_FLASH, M("TP_WBALANCE_FLASH55"), 5500)); + wbEntries.push_back(new WBEntry("Flash 6000K" ,WBT_FLASH, M("TP_WBALANCE_FLASH60"), 6000)); + wbEntries.push_back(new WBEntry("Flash 6500K" ,WBT_FLASH, M("TP_WBALANCE_FLASH65"), 6500)); + // Should remain the last one + wbEntries.push_back(new WBEntry("Custom" ,WBT_CUSTOM, M("TP_WBALANCE_CUSTOM"), 0)); +} + +void WBParams::cleanup() { + for (unsigned int i=0; igeneral.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 tonecurve: + 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); + 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 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.bwtoning) keyFile.set_boolean ("Luminance Curve", "BWtoning", labCurve.bwtoning); + 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.lccurve) { + Glib::ArrayHandle lccurve = labCurve.lccurve; + keyFile.set_double_list("Luminance Curve", "LcCurve", lccurve); + } + + // 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); + +/* + // 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 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); + + // save dirpyrDenoise + if (!pedited || pedited->dirpyrDenoise.enabled) keyFile.set_boolean ("Directional Pyramid Denoising", "Enabled", dirpyrDenoise.enabled); + 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.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", 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_integer ("Perspective", "Horizontal", perspective.horizontal); + if (!pedited || pedited->perspective.vertical) keyFile.set_integer ("Perspective", "Vertical", perspective.vertical); + + // 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); + + // save highlight recovery settings + if (!pedited || pedited->hlrecovery.enabled) keyFile.set_boolean ("HLRecovery", "Enabled", hlrecovery.enabled); + if (!pedited || pedited->hlrecovery.method) keyFile.set_string ("HLRecovery", "Method", hlrecovery.method); + + 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", 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.preferredProfile) keyFile.set_boolean ("Color Management", "PreferredProfile", icm.preferredProfile); + 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]); + } + + // 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.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", 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", 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.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); + error2 = write (fname2, sPParams); + return error1 & error2; +} + +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; } + 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; } + } +} + + // 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 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 (keyFile.has_key ("Luminance Curve", "Chromaticity")) { labCurve.chromaticity = keyFile.get_integer ("Luminance Curve", "Chromaticity"); if (pedited) pedited->labCurve.chromaticity = true; } + + if (PPVERSION < 303) { + // 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", "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 (keyFile.has_key ("Luminance Curve", "BWtoning")) { labCurve.bwtoning = keyFile.get_boolean ("Luminance Curve", "BWtoning"); if (pedited) pedited->labCurve.bwtoning = 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", "LcCurve")) { labCurve.lccurve = keyFile.get_double_list ("Luminance Curve", "LcCurve"); if (pedited) pedited->labCurve.lccurve = 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; } +} + + // 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 = keyFile.get_integer ("Defringing", "Threshold"); if (pedited) pedited->defringe.threshold = 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", "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", "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 = 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_integer ("Perspective", "Horizontal"); if (pedited) pedited->perspective.horizontal = true; } + if (keyFile.has_key ("Perspective", "Vertical")) { perspective.vertical = keyFile.get_integer ("Perspective", "Vertical"); if (pedited) pedited->perspective.vertical = 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 highlight recovery settings +if (keyFile.has_group ("HLRecovery")) { + if (keyFile.has_key ("HLRecovery", "Enabled")) { hlrecovery.enabled = keyFile.get_boolean ("HLRecovery", "Enabled"); if (pedited) pedited->hlrecovery.enabled = true; } + if (keyFile.has_key ("HLRecovery", "Method")) { hlrecovery.method = keyFile.get_string ("HLRecovery", "Method"); if (pedited) pedited->hlrecovery.method = 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 = 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", "PreferredProfile")) { icm.preferredProfile = keyFile.get_boolean ("Color Management", "PreferredProfile"); if (pedited) pedited->icm.preferredProfile = 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", "GammaVal")) { icm.gampos = keyFile.get_double ("Color Management", "GammaVal"); if (pedited) pedited->icm.gamma = 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; } + 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; } + } +} + + // 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", "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 = 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 = 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", "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; + } + 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 + && 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.lccurve == other.labCurve.lccurve + && 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.bwtoning == other.labCurve.bwtoning + && 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 + //&& colorShift.a == other.colorShift.a + //&& colorShift.b == other.colorShift.b + && impulseDenoise.enabled == other.impulseDenoise.enabled + && impulseDenoise.thresh == other.impulseDenoise.thresh + && dirpyrDenoise.enabled == other.dirpyrDenoise.enabled + && dirpyrDenoise.luma == other.dirpyrDenoise.luma + && dirpyrDenoise.Ldetail == other.dirpyrDenoise.Ldetail + && dirpyrDenoise.chroma == other.dirpyrDenoise.chroma + && 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 + //&& 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 + && 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)) + && hlrecovery.enabled == other.hlrecovery.enabled + && hlrecovery.method == other.hlrecovery.method + && 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.preferredProfile == other.icm.preferredProfile + && 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; + } +} + +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..09de24b3c --- /dev/null +++ b/rtengine/procparams.h @@ -0,0 +1,804 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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 + +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_FILMLIKE, // Film-like mode, as defined in Adobe's reference code + TC_MODE_SATANDVALBLENDING, // Modify the Saturation and Value channel + TC_MODE_WEIGHTEDSTD // Weighted standard mode + }; + + bool autoexp; + double clip; + double expcomp; + std::vector curve; + std::vector curve2; + eTCModeId curveMode; + eTCModeId curveMode2; + int brightness; + int black; + int contrast; + int saturation; + int shcompr; + int hlcompr; + int hlcomprthresh; +}; + +/** + * 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 lccurve; + int brightness; + int contrast; + int chromaticity; + bool avoidcolorshift; + double rstprotection; + bool bwtoning; + bool lcredsk; +}; + +/** + * Parameters of the RGB curves + */ +class RGBCurvesParams { + + public: + 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_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; + + WBEntry(Glib::ustring p, enum WBTypes t, Glib::ustring l, int temp) : ppLabel(p), type(t), GUILabel(l), temperature(temp) {}; +}; + +class WBParams { + + public: + static std::vector wbEntries; + Glib::ustring method; + int temperature; + double green; + + static void init(); + static void cleanup(); +}; + +/** + * 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; + int threshold; + }; + + + /** + * Parameters of impulse denoising + */ + class ImpulseDenoiseParams { + + public: + bool enabled; + int thresh; + + }; + + /** + * Parameters of the directional pyramid denoising + */ + class DirPyrDenoiseParams { + + public: + bool enabled; + double luma; + double Ldetail; + double chroma; + double gamma; + double expcomp; + }; + +//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: + int horizontal; + int vertical; +}; + +/** + * 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]; +}; + +/** + * 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; + short preferredProfile; + 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[8]; +}; + +/** + * 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,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; + 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 + //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 + CACorrParams cacorrection; ///< Lens c/a correction parameters + VignettingParams vignetting; ///< Lens vignetting correction parameters + ChannelMixerParams chmixer; ///< Channel mixer parameters + HRecParams hlrecovery; ///< Highlight recovery 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 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 = "", 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); + void applyTo (ProcParams *destParams) const ; +}; + +} +} +#endif diff --git a/rtengine/rawimage.cc b/rtengine/rawimage.cc new file mode 100644 index 000000000..afdf71e0c --- /dev/null +++ b/rtengine/rawimage.cc @@ -0,0 +1,281 @@ +/* + * This file is part of RawTherapee. + * + * Created on: 20/nov/2010 + */ + +#include "rawimage.h" +#include "settings.h" +#include "colortemp.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) +{ +} + +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_) + +{ + unsigned row, col, x, y, c, sum[8]; + unsigned W = this->get_width(); + unsigned H = this->get_height(); + int val, sat; + double dsum[8], dmin, dmax; + + for (int c = 0; c < 4; c++){ + cblack_[c] = (float) this->get_cblack(c) + (float) this->get_black();// I don't modify black and cblack of Dcraw + pre_mul_[c] = this->get_pre_mul(c); + } + if ( this->get_cam_mul(0) == -1 ) { + 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() - 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; + 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]; + } + + sat = this->get_white() - this->get_black(); + for (c = 0; c < 4; c++) + scale_mul_[c] = (pre_mul_[c] /= dmax) * 65535.0 / sat; + if (settings->verbose) { + fprintf(stderr,"Scaling with saturation %d, and\nmultipliers", sat); + for (c = 0; c < 4; c++) + fprintf(stderr, " %f", pre_mul[c]); + fputc('\n', stderr); + } +} + +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)(); + + if (raw_image) { + 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 and cblack + unsigned int minBlack = cblack[3]; + for (int c=0; c < 3; c++) + if (minBlack > cblack[c]) minBlack = cblack[c]; + for (int c=0; c < 4; c++) cblack[c] -= minBlack; + + black += minBlack; + for (int c=0; c < 4; c++) cblack[c] += black; + calcBlack=black; // safe for compatibility with darkframe substraction + black=0; // since black is already reflected in cblack now, set it to zero + } + + 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 == &rtengine::RawImage::kodak_thumb_load_raw )); +} + +bool +RawImage::get_thumbSwap() const +{ + return ((order == 0x4949) == (ntohs(0x1234) == 0x1234)) ? true : false; +} + +} //namespace rtengine diff --git a/rtengine/rawimage.h b/rtengine/rawimage.h new file mode 100644 index 000000000..beaf84bff --- /dev/null +++ b/rtengine/rawimage.h @@ -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 . + */ +#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_ ); + 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 + + unsigned calcBlack; // calculated black, like DCRAW before 9.15 + +public: + + 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_black() const { return black;} // from DCRAW 9.15 =0, but reflected in cblack + int get_calcblack() const { return calcBlack;} // simulated like DCRAW before 9.15 + int get_cblack(int i) const {return cblack[i];} + int get_white() const { 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..1ad945f84 --- /dev/null +++ b/rtengine/rawimagesource.cc @@ -0,0 +1,2579 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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; + int sy1 = ppy; + int sx2 = ppx + pp.w; + int sy2 = ppy + pp.h; + + if ((tran & TR_ROT) == TR_R180) { + sx1 = w - ppx - pp.w; + sy1 = h - ppy - pp.h; + sx2 = sx1 + pp.w; + sy2 = sy1 + pp.h; + } + else if ((tran & TR_ROT) == TR_R90) { + sx1 = ppy; + sy1 = h - ppx - pp.w; + sx2 = sx1 + pp.h; + sy2 = sy1 + pp.w; + } + else if ((tran & TR_ROT) == TR_R270) { + sx1 = w - ppy - pp.h; + sy1 = ppx; + sx2 = sx1 + pp.h; + sy2 = sy1 + pp.w; + } + + 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); + } +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void RawImageSource::getImage (ColorTemp ctemp, int tran, Imagefloat* image, PreviewProps pp, HRecParams hrp, ColorManagementParams cmp, RAWParams raw ) +{ + Glib::Mutex::Lock 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; + rm = camwb_red / rm; + gm = camwb_green / gm; + bm = camwb_blue / bm; + + /*float mul_lum = 0.299*rm + 0.587*gm + 0.114*bm; + rm /= mul_lum; + gm /= mul_lum; + bm /= mul_lum;*/ + + /*//initialGain=1.0; + // in floating point, should keep white point fixed and recover higher values with exposure slider + //if (hrp.enabled) */ + float min = rm; + if (min>gm) min = gm; + if (min>bm) min = bm; + defGain=0.0;// = log(initialGain) / log(2.0); + //printf(" Initial gain=%f defgain=%f min=%f\n",initialGain,defGain,min); + //printf(" rm=%f gm=%f bm=%f\n",rm,gm,bm); + min/=initialGain; + //min=(float)1.0/min; + //else { + //defGain = 0.0; + rm /= min; + gm /= min; + bm /= min; + //} + //defGain = 0.0;//no need now for making headroom for highlights??? + //printf("initial gain= %e\n",initialGain); + //TODO: normalize the gain control + + + + + + //if (hrp.enabled==true && hrp.method=="Color" && hrmap[0]==NULL) + // updateHLRecoveryMap_ColorPropagation (); + + // 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 + { +#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, RAWParams raw) { + colorSpaceConversion (image, cmp, 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) + */ +int RawImageSource::findHotDeadPixel( PixelsMap &bpMap, float thresh) +{ + volatile int counter=0; + + float (*cfablur); + cfablur = (float (*)) calloc (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],cfablur[i*W+j]); + } + } + +#pragma omp for + //cfa pixel heat/death evaluation + for (int rr=0; rr < H; rr++) { + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + for (int cc=0; cc < W; cc++) { + //rawData[rr][cc] = cfablur[rr*W+cc];//diagnostic + + //evaluate pixel for heat/death + float pixdev = fabs(rawData[rr][cc]-cfablur[rr*W+cc]); + float hfnbrave=0; + int top=max(0,rr-2); + int bottom=min(H-1,rr+2); + int left=max(0,cc-2); + int right=min(W-1,cc+2); + for (int mm=top; mm<=bottom; mm++) + for (int nn=left; nn<=right; nn++) { + hfnbrave += fabs(rawData[mm][nn]-cfablur[mm*W+nn]); + } + hfnbrave = (hfnbrave-pixdev)/((bottom-top+1)*(right-left+1)-1); + + if (pixdev > thresh*hfnbrave) { + // mark the pixel as "bad" + bpMap.set(cc,rr ); + counter++; + } + }//end of pixel evaluation + + + } + }//end pragma + free (cfablur); + //printf ("counter %d \n",counter); + return counter; +} + +void RawImageSource::rotateLine (float* line, float** 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) { + int width = image->width; + int height = image->height; + + float* rowr = new float[width]; + float* rowg = new float[width]; + float* rowb = new float[width]; + for (int i=0; ir[i][width-1-j]; + rowg[j] = image->g[i][width-1-j]; + rowb[j] = image->b[i][width-1-j]; + } + memcpy (image->r[i], rowr, width*sizeof(float)); + memcpy (image->g[i], rowg, width*sizeof(float)); + memcpy (image->b[i], rowb, width*sizeof(float)); + } + delete [] rowr; + delete [] rowg; + delete [] rowb; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void RawImageSource::vflip (Imagefloat* image) { + int width = image->width; + int height = image->height; + + float tmp; + for (int i=0; ir[i][j]; + image->r[i][j] = image->r[height-1-i][j]; + image->r[height-1-i][j] = tmp; + tmp = image->g[i][j]; + image->g[i][j] = image->g[height-1-i][j]; + image->g[height-1-i][j] = tmp; + tmp = image->b[i][j]; + image->b[i][j] = image->b[height-1-i][j]; + image->b[height-1-i][j] = tmp; + } +} + + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +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); + + float pre_mul[4]; + ri->get_colorsCoeff( pre_mul, scale_mul, c_black);//modify for black level + + camwb_red = ri->get_pre_mul(0) / pre_mul[0]; + camwb_green = ri->get_pre_mul(1) / pre_mul[1]; + camwb_blue = ri->get_pre_mul(2) / pre_mul[2]; + initialGain = 1.0 / min(pre_mul[0], pre_mul[1], 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; + + wb = ColorTemp (cam_r, cam_g, cam_b); + + 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); + + 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::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(HRecParams hrp ) +{ + //color propagation highlight recovery + if (hrp.enabled && 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=ri->get_calcblack(); + + 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++) { + rawData[row][col] = max(src->data[row][col]+black - 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++) { + refcolor[m][n] = max(0.0f,cfablur[(2*(H>>2)+m)*W+2*(W>>2)+n] - black); + } + + 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) { + vignettecorr = ( refcolor[m][n]/max(1e-5f,cfablur[(row+m)*W+col+n]-black) ); + rawData[row+m][col+n] = (rawData[row+m][col+n]-black) * vignettecorr + black; + } + } + + 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) { + hlinecorr = (max(1e-5f,cfablur[(row+m)*W+col+n]-black)/max(1e-5f,cfablur1[(row+m)*W+col+n]-black) ); + vlinecorr = (max(1e-5f,cfablur[(row+m)*W+col+n]-black)/max(1e-5f,cfablur2[(row+m)*W+col+n]-black) ); + rawData[row+m][col+n] = ((rawData[row+m][col+n]-black) * hlinecorr * vlinecorr + black); + } + } + 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++) { + rawData[row][3*col+0] = max(src->data[row][3*col+0]+black - riDark->data[row][3*col+0], 0); + rawData[row][3*col+1] = max(src->data[row][3*col+1]+black - riDark->data[row][3*col+1], 0); + rawData[row][3*col+2] = max(src->data[row][3*col+2]+black - 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() ){ + 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); + chmax[c] = max(chmax[c],val); + } + } + }else{ + 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); + chmax[c] = max(chmax[c],val); + } + } + } + + 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 ppx=0, 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 + } + } +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +// Converts raw image including ICC input profile to working space - floating point version +void RawImageSource::colorSpaceConversion (Imagefloat* im, ColorManagementParams cmp, RAWParams raw, cmsHPROFILE embedded, cmsHPROFILE camprofile, double camMatrix[3][3], 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) { + dcpProf->Apply(im, (DCPLightType)cmp.preferredProfile, cmp.working, (float)raw.expos, cmp.toneCurve); + } else { + // 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 + + + if (in==NULL) { + // use default camprofile, supplied by dcraw + // in this case we avoid using the slllllooooooowwww lcms + + #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 { + Imagefloat* imgPreLCMS=NULL; + if (cmp.blendCMSMatrix) imgPreLCMS=im->copy(); + + // use supplied input profile + // color space transform is expecting data in the range (0,1) + #pragma omp parallel for + for ( int h = 0; h < im->height; ++h ) + for ( int w = 0; w < im->width; ++w ) { + im->r[h][w] /= 65535.0f ; + im->g[h][w] /= 65535.0f ; + im->b[h][w] /= 65535.0f ; + } + + + // 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] = pow (max(im->r[h][w],0.0f), gammaFac); + im->g[h][w] = pow (max(im->g[h][w],0.0f), gammaFac); + im->b[h][w] = pow (max(im->b[h][w],0.0f), gammaFac); + } + } + + + if(settings->gamutICC) + // use Prophoto to apply profil ICC, then converted to cmp.working (sRGB..., Adobe.., Wide..) to avoid color shifts due to relative colorimetric + // LCMS use intent for applying profil => suppression of negatives values and > 65535 + //useful for correcting Munsell Lch + + { if( settings->verbose ) printf("With Gamut ICC correction float\n"); + Glib::ustring profi ="ProPhoto"; + cmsHPROFILE out = iccStore->workingSpace (profi);//Prophoto + TMatrix wprof = iccStore->workingSpaceMatrix (profi); + TMatrix wiprof = iccStore->workingSpaceInverseMatrix (cmp.working);//sRGB .. Adobe...Wide... + double toxyz[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]) + } + }; + lcmsMutex->lock (); + cmsHTRANSFORM hTransform = cmsCreateTransform (in, TYPE_RGB_FLT, out, TYPE_RGB_FLT, + INTENT_RELATIVE_COLORIMETRIC, // float is clipless, so don't trim it + cmsFLAGS_NOCACHE ); // NOCACHE is important for thread safety + lcmsMutex->unlock (); + if (hTransform) { + im->ExecCMSTransform(hTransform); + } + else { + // create the profile from camera + lcmsMutex->lock (); + hTransform = cmsCreateTransform (camprofile, TYPE_RGB_FLT, out, TYPE_RGB_FLT, settings->colorimetricIntent, + cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is important for thread safety + lcmsMutex->unlock (); + + im->ExecCMSTransform(hTransform); + } + Glib::ustring choiceprofile; + choiceprofile=cmp.working; + if(choiceprofile!="ProPhoto") { + #pragma omp parallel for + for ( int h = 0; h < im->height; ++h ) + for ( int w = 0; w < im->width; ++w ) {//convert from Prophoto to XYZ + float x, y,z; + x = (toxyz[0][0] * im->r[h][w] + toxyz[0][1] * im->g[h][w] + toxyz[0][2] * im->b[h][w] ) ; + y = (toxyz[1][0] * im->r[h][w] + toxyz[1][1] * im->g[h][w] + toxyz[1][2] * im->b[h][w] ) ; + z = (toxyz[2][0] * im->r[h][w] + toxyz[2][1] * im->g[h][w] + toxyz[2][2] * im->b[h][w] ) ; + //convert from XYZ to cmp.working (sRGB...Adobe...Wide..) + im->r[h][w] = ((wiprof[0][0]*x + wiprof[0][1]*y + wiprof[0][2]*z)) ; + im->g[h][w] = ((wiprof[1][0]*x + wiprof[1][1]*y + wiprof[1][2]*z)) ; + im->b[h][w] = ((wiprof[2][0]*x + wiprof[2][1]*y + wiprof[2][2]*z)) ; + } + } + + cmsDeleteTransform(hTransform); + + } + else { + if( settings->verbose ) printf("Without Gamut ICC correction float\n"); + cmsHPROFILE out = iccStore->workingSpace (cmp.working); + +// out = iccStore->workingSpaceGamma (wProfile); + lcmsMutex->lock (); + cmsHTRANSFORM hTransform = cmsCreateTransform (in, TYPE_RGB_FLT, out, TYPE_RGB_FLT, + INTENT_RELATIVE_COLORIMETRIC, // float is clipless, so don't trim it + cmsFLAGS_NOCACHE ); // NOCACHE is important for thread safety + lcmsMutex->unlock (); + + if (hTransform) { + // there is an input profile + im->ExecCMSTransform(hTransform); + } else { + // create the profile from camera + lcmsMutex->lock (); + hTransform = cmsCreateTransform (camprofile, TYPE_RGB_FLT, out, TYPE_RGB_FLT, settings->colorimetricIntent, + cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is important for thread safety + lcmsMutex->unlock (); + + im->ExecCMSTransform(hTransform); + } + + cmsDeleteTransform(hTransform); + } + + // restore normalization to the range (0,65535) and blend matrix colors if LCMS is clipping + const float RecoverTresh = 65535.0 * 0.98; // just the last few percent highlights are merged + #pragma omp parallel for + for ( int h = 0; h < im->height; ++h ) + for ( int w = 0; w < im->width; ++w ) { + + // There might be Nikon postprocessings + if (lineSum>0) { + im->r[h][w] *= im->r[h][w] * lineFac + lineSum; + im->g[h][w] *= im->g[h][w] * lineFac + lineSum; + im->b[h][w] *= im->b[h][w] * lineFac + lineSum; + } + + im->r[h][w] *= 65535.0 ; + im->g[h][w] *= 65535.0 ; + im->b[h][w] *= 65535.0 ; + + if (cmp.blendCMSMatrix) { + // Red + float red=im->r[h][w]; + if (red>RecoverTresh) { + float matrixRed = mat[0][0]*imgPreLCMS->r[h][w] + mat[0][1]*imgPreLCMS->g[h][w] + mat[0][2]*imgPreLCMS->b[h][w]; + + if (red>=65535.0) + im->r[h][w] = matrixRed; + else { + float fac = (red - RecoverTresh) / (65535.0 - RecoverTresh); + im->r[h][w] = (1.0-fac) * red + fac * matrixRed; + } + } + + // Green + float green=im->g[h][w]; + if (green>RecoverTresh) { + float matrixGreen = mat[1][0]*imgPreLCMS->r[h][w] + mat[1][1]*imgPreLCMS->g[h][w] + mat[1][2]*imgPreLCMS->b[h][w]; + + if (green>=65535.0) + im->g[h][w] = matrixGreen; + else { + float fac = (green - RecoverTresh) / (65535.0 - RecoverTresh); + im->g[h][w] = (1.0-fac) * green + fac * matrixGreen; + } + } + + + // Blue + float blue=im->b[h][w]; + if (blue>RecoverTresh) { + float matrixBlue = mat[2][0]*imgPreLCMS->r[h][w] + mat[2][1]*imgPreLCMS->g[h][w] + mat[2][2]*imgPreLCMS->b[h][w]; + + if (blue>=65535.0) + im->b[h][w] = matrixBlue; + else { + float fac = (blue - RecoverTresh) / (65535.0 - RecoverTresh); + im->b[h][w] = (1.0-fac) * blue + fac * matrixBlue; + } + } + } + } + + if (imgPreLCMS!=NULL) delete imgPreLCMS; + } + } + //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; + + float clipfrac[3]; + FOREACHCOLOR clipfrac[c] = min(1.0f,rgb[c]/maxave); + + // 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/MAXVAL)/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/MAXVAL)/3.0 ))); + y = (y<65535.0 ? ImProcFunctions::cachef[y]/327.68 : (exp(log(y/MAXVAL)/3.0 ))); + z = (z<65535.0 ? ImProcFunctions::cachef[z]/327.68 : (exp(log(z/MAXVAL)/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(); + + for (int i=border; iisBayer()) { + for (int j=start; jISGREEN(i,j)) histogram[CLIP((int)(camwb_green*rawData[i][j]))>>histcompr]+=4; + else if (ri->ISRED(i,j)) histogram[CLIP((int)(camwb_red* rawData[i][j]))>>histcompr]+=4; + else if (ri->ISBLUE(i,j)) histogram[CLIP((int)(camwb_blue* rawData[i][j]))>>histcompr]+=4; + } + } else { + for (int j=start; j>histcompr]++; + histogram[CLIP((int)(camwb_green*rawData[i][3*j+1]))>>histcompr]+=2; + histogram[CLIP((int)(camwb_blue* rawData[i][3*j+2]))>>histcompr]++; + } + } + } +} + +// 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 = 65535.0 / ri->get_white(); + + // WARNING: This parallelization is not thread-safe because it R/W in histRedRaw, histGreenRaw, histBlueRaw + // which are defined before the parallel section and must survive after it + #pragma omp parallel for + for (int i=border; iisBayer()) { + for (int j=start; jdata[i][j]-(cblacksom[c4]/*+black_lev[c4]*/)))); + + switch (c) { + case 0: histRedRaw[idx>>8]++; break; + case 1: histGreenRaw[idx>>8]++; break; + case 2: histBlueRaw[idx>>8]++; break; + } + } + } else { + for (int j=start; jdata[i][3*j+c]-cblacksom[c]))); + + switch (c) { + case 0: histRedRaw[idx>>8]++; break; + case 1: histGreenRaw[idx>>8]++; break; + case 2: histBlueRaw[idx>>8]++; break; + } + } + } + } + } + + // 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; + } +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + ColorTemp RawImageSource::getAutoWB () { + + 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 d = CLIP(initialGain*(rawData[i][3*j])); + if (d>64000) + continue; + avg_r += d; rn++; + d = CLIP(initialGain*(rawData[i][3*j+1])); + if (d>64000) + continue; + avg_g += d; gn++; + d = CLIP(initialGain*(rawData[i][3*j+2])); + if (d>64000) + continue; + avg_b += d; bn++; + } + else { + int c = FC( i, j); + double d = CLIP(initialGain*(rawData[i][j])); + if (d>64000) + continue; + double dp = d; + if (c==0) { + avg_r += dp; + rn++; + } + else if (c==1) { + avg_g += dp; + gn++; + } + else if (c==2) { + avg_b += dp; + 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; i64000 || d[0][1]>64000 || d[1][0]>64000 || d[1][1]>64000 ) continue; + avg_r += d[ey][ex]; + avg_g += d[1-ey][ex] + d[ey][1-ex]; + avg_b += d[1-ey][1-ex]; + rn++; + } + gn = 2*rn; + bn = rn; + } + } + if( settings->verbose ) + 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 * camwb_red; + double greens = avg_g/gn * camwb_green; + double blues = avg_b/bn * camwb_blue; + + double rm = imatrices.rgb_cam[0][0]*reds + imatrices.rgb_cam[0][1]*greens + imatrices.rgb_cam[0][2]*blues; + double gm = imatrices.rgb_cam[1][0]*reds + imatrices.rgb_cam[1][1]*greens + imatrices.rgb_cam[1][2]*blues; + double bm = imatrices.rgb_cam[2][0]*reds + imatrices.rgb_cam[2][1]*greens + imatrices.rgb_cam[2][2]*blues; + + return ColorTemp (rm, gm, bm); + } + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + ColorTemp RawImageSource::getSpotWB (std::vector red, std::vector green, std::vector& blue, int tran) { + + 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 && 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; +} + + + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +//#include "demosaic_algos.cc" + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +//Emil's code +#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..e8794801f --- /dev/null +++ b/rtengine/rawimagesource.h @@ -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 . + */ +#ifndef _RAWIMAGESOURCE_ +#define _RAWIMAGESOURCE_ + +#include "imagesource.h" +#include +#include "dcp.h" +#include "array2D.h" +#include "curves.h" +#include +#include "color.h" +#include "../rtgui/cacheimagedata.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, float** 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 (HRecParams hrp); + //void refinement_lassus (); + + 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, HRecParams hrp, ColorManagementParams cmp, RAWParams raw); + ColorTemp getWB () { return wb; } + ColorTemp getAutoWB (); + ColorTemp getSpotWB (std::vector red, std::vector green, std::vector& blue, int tran); + 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, 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, RAWParams raw, cmsHPROFILE embedded, cmsHPROFILE camprofile, double cam[3][3], std::string 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); + + 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, float* pfMatr, float* pfVect, float* pfSolution);//Emil's CA auto correction + void CA_correct_RT (double cared, double cablue); + void ddct8x8s(int isgn, float **a); + 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 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(int border, float (*image)[4], int start = 0, int end = 0); + 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..30e3ef633 --- /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] = 903.3 * y / MAXVAL; + + oa[j] = 500.0 * ((x>threshold ? cache[(int)x] : 7.787*x/MAXVAL+16.0/116.0) - (y>threshold ? cache[(int)y] : 7.787*y/MAXVAL+16.0/116.0)); + ob[j] = 200.0 * ((y>threshold ? cache[(int)y] : 7.787*y/MAXVAL+16.0/116.0) - (z>threshold ? cache[(int)z] : 7.787*z/MAXVAL+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..2fc494523 --- /dev/null +++ b/rtengine/refreshmap.cc @@ -0,0 +1,197 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#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, // EvPrefProfile, +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, // EvVignetting, +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 +0, // EvEqlEnabled:obsolete +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 +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 +LUMINANCECURVE, // EvLBWtoning +LUMINANCECURVE, // EvLCCurve +LUMINANCECURVE, // EvLCHCurve +RGBCURVE, // EvVibranceSkinTonesCurve +LUMINANCECURVE, // EvLLCCurve +LUMINANCECURVE, // EvLLCredsk +ALLNORAW // EvDPDNLdetail +}; + diff --git a/rtengine/refreshmap.h b/rtengine/refreshmap.h new file mode 100644 index 000000000..00bdabada --- /dev/null +++ b/rtengine/refreshmap.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 __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") +#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_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_MINUPDATE +#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 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..9f8797c2d --- /dev/null +++ b/rtengine/rt_math.h @@ -0,0 +1,70 @@ +#ifndef _MYMATH_ +#define _MYMATH_ +#include +#include + +#include "rtengine.h" + +namespace rtengine { + static const int MAXVAL = 0xffff; + + 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)); + //return ((a)>0.0? ((a) + 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..3740c787f --- /dev/null +++ b/rtengine/rtengine.h @@ -0,0 +1,405 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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 "procparams.h" +#include "procevents.h" +#include +#include +#include +#include +#include "../rtexif/rtexif.h" +#include "rawmetadatalocation.h" +#include "iimage.h" +#include "utils.h" +#include "settings.h" +#include "LUT.h" +/** + * @file + * This file contains the main functionality of the raw therapee engine. + * + */ + + +namespace rtengine { + + /** + * 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: + /** 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: + /** 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: + /** 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: + /** 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: + /** 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 & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw) {} + }; + + /** This listener is used when the auto exposure has been recomputed (e.g. when the clipping ratio changed). */ + class AutoExpListener { + public: + /** 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*/ + virtual void autoExpChanged (double brightness, int bright, int contrast, int black, int hlcompr, int hlcomprthresh) {} + }; + + /** 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: + /** 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) =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 ~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); + }; + + +/** + * Initializes the RT engine + * @param s is a struct of basic settings, baseDir of RT */ + int init (const Settings* s, Glib::ustring baseDir); + +/** 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 (); +/** return gamma */ + 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; + }; +/** 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 Glib::Mutex* 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..7275066d8 --- /dev/null +++ b/rtengine/rtthumbnail.cc @@ -0,0 +1,1457 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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 "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" + +namespace rtengine { + +Thumbnail* Thumbnail::loadFromImage (const Glib::ustring& fname, int &w, int &h, int fixwh, int deg) { + + Image16* img = new Image16 (); + int err = img->load (fname); + if (err) { + delete img; + return NULL; + } + if (deg) { + Image16* rot = img->rotate(deg); + delete img; + img = rot; + } + + Thumbnail* tpp = new Thumbnail (); + + tpp->camwbRed = 1.0; + tpp->camwbGreen = 1.0; + tpp->camwbBlue = 1.0; + + tpp->embProfileLength = 0; + 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); + } + else { + tpp->embProfileLength = 0; + tpp->embProfileData = NULL; + } + + tpp->redMultiplier = 1.0; + tpp->greenMultiplier = 1.0; + tpp->blueMultiplier = 1.0; + + 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 = img->resize (w, h, TI_Bilinear); + + // 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; + + tpp->aeHistogram.clear(); + int ix = 0; + for (int i=0; iheight*img->width; i++) { + int rtmp=Color::igamma_srgb (img->data[ix++]); + int gtmp=Color::igamma_srgb (img->data[ix++]); + int btmp=Color::igamma_srgb (img->data[ix++]); + + tpp->aeHistogram[rtmp>>tpp->aeHistCompression]++; + tpp->aeHistogram[gtmp>>tpp->aeHistCompression]+=2; + tpp->aeHistogram[btmp>>tpp->aeHistCompression]++; + + if (rtmp<64000 && gtmp<64000 && btmp<64000) { + // autowb computation + avg_r += rtmp; + avg_g += gtmp; + avg_b += btmp; + n++; + } + } + + if (n>0) { + ColorTemp cTemp; + cTemp.mul2temp (avg_r/n, avg_g/n, avg_b/n, tpp->autowbTemp, tpp->autowbGreen); + } + + delete img; + 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(); + + Image16* img = new Image16 (); + + 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->camwbRed = 1.0; + tpp->camwbGreen = 1.0; + tpp->camwbBlue = 1.0; + + tpp->embProfileLength = 0; + tpp->embProfile = NULL; + tpp->embProfileData = NULL; + + tpp->redMultiplier = 1.0; + tpp->greenMultiplier = 1.0; + tpp->blueMultiplier = 1.0; + + tpp->scaleForSave = 8192; + tpp->defGain = 1.0; + tpp->gammaCorrected = false; + 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 = img->resize (w, h, TI_Nearest); + delete img; + + tpp->autowbTemp=2700; + tpp->autowbGreen=1.0; + + if (rotate && ri->get_rotateDegree() > 0) { + // Leaf .mos, Mamiya .mef and Phase One files have thumbnails already rotated. + if (ri->get_maker() != "Leaf" && ri->get_maker() != "Mamiya" && ri->get_maker() != "Phase One") { + Image16* rot = tpp->thumbImg->rotate(ri->get_rotateDegree()); + delete tpp->thumbImg; + tpp->thumbImg = rot; + } + } + + 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) + +Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, int &w, int &h, int fixwh, 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()) { + 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; + + Image16* resImg;// = new Image16(tmpw, tmph);<< memory leak!! + resImg = tmpImg->to16(); + delete tmpImg; + + if (tpp->thumbImg) delete tpp->thumbImg; + tpp->thumbImg = resImg->resize(w, h, TI_Bilinear); + delete resImg; + + + 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; + float rn = 0.0, gn = 0.0, bn = 0.0; + + 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++; + } + if (FISRED(filter,i,j)) { + double d = tpp->defGain * image[i * width + j][0]; + if (d > 64000) + continue; + avg_r += d; + rn++; + } + 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; + + double rm = ri->get_rgb_cam(0, 0) * reds + ri->get_rgb_cam(0, 1) * greens + ri->get_rgb_cam(0, 2) * blues; + double gm = ri->get_rgb_cam(1, 0) * reds + ri->get_rgb_cam(1, 1) * greens + ri->get_rgb_cam(1, 2) * blues; + double bm = ri->get_rgb_cam(2, 0) * reds + ri->get_rgb_cam(2, 1) * greens + ri->get_rgb_cam(2, 2) * blues; + + ColorTemp cTemp; + cTemp.mul2temp(rm, gm, bm, tpp->autowbTemp, tpp->autowbGreen); + + if (rotate && ri->get_rotateDegree() > 0) { + Image16* rot = tpp->thumbImg->rotate(ri->get_rotateDegree()); + delete tpp->thumbImg; + tpp->thumbImg = rot; + } + + 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), embProfileData(NULL), embProfile(NULL) { +} + +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, 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; + Image16* tmp = thumbImg->resize (rwidth, rheight, interp); + Imagefloat* baseImg = tmp->tofloat(); + + if (params.coarse.rotate) { + Imagefloat* tmp = baseImg->rotate (params.coarse.rotate); + rwidth = tmp->width; + rheight = tmp->height; + delete baseImg; + baseImg = tmp; + } + if (params.coarse.hflip) { + Imagefloat* tmp = baseImg->hflip (); + delete baseImg; + baseImg = tmp; + } + if (params.coarse.vflip) { + Imagefloat* tmp = baseImg->vflip (); + delete baseImg; + baseImg = tmp; + } + Image8* img8 = baseImg->to8(); + delete baseImg; + //delete tmp; + return img8; +} + +// 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, double& myscale) { + + // compute WB multipliers + ColorTemp currWB = ColorTemp (params.wb.temperature, params.wb.green, 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); + } + else if (params.wb.method=="Auto") + currWB = ColorTemp (autowbTemp, autowbGreen, "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.hlrecovery.enabled) { + 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 = thumbImg->height * rwidth / thumbImg->width; + } + else + rwidth = thumbImg->width * rheight / thumbImg->height; + + Image16* resImg = thumbImg->resize (rwidth, rheight, interp); + + if (params.coarse.rotate) { + Image16* tmp = resImg->rotate (params.coarse.rotate); + rwidth = tmp->width; + rheight = tmp->height; + delete resImg; + resImg = tmp; + } + if (params.coarse.hflip) { + Image16* tmp = resImg->hflip (); + delete resImg; + resImg = tmp; + } + if (params.coarse.vflip) { + Image16* tmp = resImg->vflip (); + delete resImg; + resImg = tmp; + } + // apply white balance and raw white point (simulated) + int val; + for (int i=0; ir[i][j]*rmi)>>10; + resImg->r[i][j] = CLIP(val); + val = ((int)resImg->g[i][j]*gmi)>>10; + resImg->g[i][j] = CLIP(val); + val = ((int)resImg->b[i][j]*bmi)>>10; + resImg->b[i][j] = CLIP(val); + } + +/* + // apply highlight recovery, if needed -- CURRENTLY BROKEN DUE TO INCOMPATIBLE DATA TYPES; DO WE CARE??? + if (isRaw && params.hlrecovery.enabled) { + int maxval = 65535 / defGain; + if (params.hlrecovery.method=="Luminance" || params.hlrecovery.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.hlrecovery.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::colorSpaceConversion16 (resImg, params.icm, embProfile, camProfile, cam2xyz, camName ); + else + StdImageSource::colorSpaceConversion16 (resImg, params.icm, embProfile); + + Imagefloat* baseImg = resImg->tofloat(); + delete resImg;// << avoid mem leak! + int fw = baseImg->width; + int fh = baseImg->height; + + 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); + 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); + ipf.transform (baseImg, trImg, 0, 0, 0, 0, fw, fh, 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 rCurve (65536); + LUTf gCurve (65536); + LUTf bCurve (65536); + + LUTu dummy; + + ToneCurve customToneCurve1, customToneCurve2; + + 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); + + ipf.rgbProc (baseImg, labView, curve1, curve2, curve, shmap, params.toneCurve.saturation, rCurve, gCurve, bCurve, customToneCurve1, customToneCurve2, expcomp, hlcompr, hlcomprthresh); + + if (shmap) + delete shmap; + + // luminance histogram update + hist16.clear(); + for (int i=0; iL[i][j])))]++; + + // luminance processing + ipf.EPDToneMap(labView,0,6); + bool utili=false; + bool autili=false; + bool butili=false; + bool ccutili=false; + bool cclutili=false; + CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, + hist16, hist16, curve, dummy, 16, utili); + 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, 16); + //ipf.luminanceCurve (labView, labView, curve); + ipf.chromiLuminanceCurve (labView, labView, curve1, curve2, satcurve,lhskcurve, curve, utili, autili, butili, ccutili,cclutili); + ipf.vibrance(labView); + + // color processing + //ipf.colorCurve (labView, labView); + + // obtain final image + Image8* readyImg = new Image8 (fw, fh); + ipf.lab2monitorRgb (labView, readyImg); + delete labView; + delete baseImg; + + // calculate scale + if (params.coarse.rotate==90 || params.coarse.rotate==270) + myscale = scale * thumbImg->width / fh; + else + myscale = scale * thumbImg->height / fh; + + myscale = 1.0 / myscale; + +/* // apply crop + if (params.crop.enabled) { + int ix = 0; + for (int i=0; i(params.crop.y+params.crop.h)/myscale || j(params.crop.x+params.crop.w)/myscale) { + readyImg->data[ix++] /= 3; + readyImg->data[ix++] /= 3; + readyImg->data[ix++] /= 3; + } + else + ix += 3; + }*/ + return readyImg; +} + +int Thumbnail::getImageWidth (const procparams::ProcParams& params, int rheight, float &ratio) { + if (thumbImg==NULL) return 0; // Can happen if thumb is just building and GUI comes in with resize wishes + + int rwidth; + if (params.coarse.rotate==90 || params.coarse.rotate==270) { + ratio = (float)(thumbImg->height) / (float)(thumbImg->width); + } + else { + ratio = (float)(thumbImg->width) / (float)(thumbImg->height); + } + rwidth = (int)(ratio * (float)rheight); + + return rwidth; +} + +void Thumbnail::getDimensions (int& w, int& h, double& scaleFac) { + if (thumbImg) { + w=thumbImg->width; h=thumbImg->height; scaleFac=scale; + } else { + w=0; h=0; scale=1; + } +} + +void Thumbnail::getCamWB (double& temp, double& green) { + + double cam_r = colorMatrix[0][0]*camwbRed + colorMatrix[0][1]*camwbGreen + colorMatrix[0][2]*camwbBlue; + double cam_g = colorMatrix[1][0]*camwbRed + colorMatrix[1][1]*camwbGreen + colorMatrix[1][2]*camwbBlue; + double cam_b = colorMatrix[2][0]*camwbRed + colorMatrix[2][1]*camwbGreen + colorMatrix[2][2]*camwbBlue; + ColorTemp currWB = ColorTemp (cam_r, cam_g, cam_b); + temp = currWB.getTemp (); + green = currWB.getGreen (); +} + +void Thumbnail::getAutoWB (double& temp, double& green) { + + temp = autowbTemp; + green = autowbGreen; +} + +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) + unsigned short igammatab[256]; + for (int i=0; i<256; i++) + igammatab[i] = (unsigned short)(255.0*pow(i/255.0,Color::sRGBGamma)); + int x; int y; + double reds = 0, greens = 0, blues = 0; + int rn = 0, gn = 0, bn = 0; + for (size_t i=0; i=0 && y>=0 && xwidth && yheight) { + reds += thumbImg->r[y][x]; + rn++; + } + transformPixel (green[i].x, green[i].y, tr, x, y); + if (x>=0 && y>=0 && xwidth && yheight) { + greens += thumbImg->g[y][x]; + gn++; + } + transformPixel (blue[i].x, blue[i].y, tr, x, y); + if (x>=0 && y>=0 && xwidth && yheight) { + blues += thumbImg->b[y][x]; + bn++; + } + } + 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); + 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); + + for (int row=0; rowheight; row++) + for (int col=0; colwidth; col++) { + hist16[thumbImg->r[row][col]]++; + hist16[thumbImg->g[row][col]]+=2; // Bayer 2x green correction + hist16[thumbImg->b[row][col]]++; + } + + // 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 && sumheight; i++) + for (int j=(thumbImg->width-trim_width)/2; jwidth-trim_width)/2; j++) { + int r= gammatab[min(thumbImg->r[i][j],static_cast(max_)) * scaleForSave >> 13]; + int g= gammatab[min(thumbImg->g[i][j],static_cast(max_)) * scaleForSave >> 13]; + int b= gammatab[min(thumbImg->b[i][j],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; + + for (int row=0; rowheight; row++) + for (int col=0; colwidth; col++) { + if (thumbImg->r[row][col]>max) max = thumbImg->r[row][col]; + if (thumbImg->g[row][col]>max) max = thumbImg->g[row][col]; + if (thumbImg->b[row][col]>max) max = thumbImg->b[row][col]; + } + + if (max < 16384) max = 16384; + scaleForSave = 65535*8192 / max; + + // Correction and gamma to 8 Bit + for (int i=0; iheight; i++) + for (int j=(thumbImg->width-trim_width)/2; jwidth-trim_width)/2; j++) { + int r=thumbImg->r[i][j] * scaleForSave >> 21; + int g=thumbImg->g[i][j] * scaleForSave >> 21; + int b=thumbImg->b[i][j] * scaleForSave >> 21; + tmpdata[ix++] = (r*19595+g*38469+b*7472)>>16; + } + } + + // 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; iheight*thumbImg->width*3]; + 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); + + for (int row=0; rowheight; row++) + for (int col=0; colwidth; col++) { + hist16[thumbImg->r[row][col]]++; + hist16[thumbImg->g[row][col]]+=2; // Bayer 2x green correction + hist16[thumbImg->b[row][col]]++; + } + + // 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 && sumheight; i++) + for (int j=0; jwidth; j++) { + tmpdata[ix++] = gammatab[min(thumbImg->r[i][j],static_cast(max_)) * scaleForSave >> 13]; + tmpdata[ix++] = gammatab[min(thumbImg->g[i][j],static_cast(max_)) * scaleForSave >> 13]; + tmpdata[ix++] = gammatab[min(thumbImg->b[i][j],static_cast(max_)) * scaleForSave >> 13]; + } + } + else { + // If it's not gamma corrected (usually a JPG) we take the normal maximum + max=0; + + for (int row=0; rowheight; row++) + for (int col=0; colwidth; col++) { + if (thumbImg->r[row][col]>max) max = thumbImg->r[row][col]; + if (thumbImg->g[row][col]>max) max = thumbImg->g[row][col]; + if (thumbImg->b[row][col]>max) max = thumbImg->b[row][col]; + } + + if (max < 16384) max = 16384; + scaleForSave = 65535*8192 / max; + + // Correction and gamma to 8 Bit + for (int i=0; iheight; i++) + for (int j=0; jwidth; j++) { + tmpdata[ix++] = thumbImg->r[i][j]*scaleForSave >> 21; + tmpdata[ix++] = thumbImg->g[i][j]*scaleForSave >> 21; + tmpdata[ix++] = thumbImg->b[i][j]*scaleForSave >> 21; + } + } + + if (format==1) { + FILE* f = safe_g_fopen (fname, "wb"); + if (!f) { + delete [] tmpdata; + return false; + } + fwrite (&thumbImg->width, 1, sizeof (int), f); + fwrite (&thumbImg->height, 1, sizeof (int), f); + fwrite (tmpdata, thumbImg->width*thumbImg->height, 3, f); + fclose (f); + } + else if (format==3) { + FILE* f = safe_g_fopen (fname, "wb"); + if (!f) { + delete [] tmpdata; + return false; + } + jpeg_compress_struct cinfo; + jpeg_error_mgr jerr; + cinfo.err = jpeg_std_error (&jerr); + jpeg_create_compress (&cinfo); + jpeg_stdio_dest (&cinfo, f); + cinfo.image_width = thumbImg->width; + cinfo.image_height = thumbImg->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; + + jpeg_set_quality (&cinfo, 87, true); + jpeg_start_compress(&cinfo, TRUE); + while (cinfo.next_scanline < cinfo.image_height) { + unsigned char* row = tmpdata + cinfo.next_scanline*thumbImg->width*3; + if (jpeg_write_scanlines (&cinfo, &row, 1) < 1) { + jpeg_finish_compress (&cinfo); + jpeg_destroy_compress (&cinfo); + fclose (f); + delete [] tmpdata; + return false; + } + } + jpeg_finish_compress (&cinfo); + jpeg_destroy_compress (&cinfo); + fclose (f); + } + delete [] tmpdata; + return true; + } + else if (format==2) { + FILE* f = safe_g_fopen (fname, "wb"); + if (!f) + return false; + fwrite (&thumbImg->width, 1, sizeof (int), f); + fwrite (&thumbImg->height, 1, sizeof (int), f); + for (int i=0; iheight; i++) + fwrite (thumbImg->r[i], thumbImg->width, 2, f); + for (int i=0; iheight; i++) + fwrite (thumbImg->g[i], thumbImg->width, 2, f); + for (int i=0; iheight; i++) + fwrite (thumbImg->b[i], thumbImg->width, 2, f); + fclose (f); + return true; + } + else + return false; +} + +bool Thumbnail::readImage (const Glib::ustring& fname) { + + delete thumbImg; + thumbImg = NULL; + + int imgType = 0; + if (safe_file_test (fname+".cust16", Glib::FILE_TEST_EXISTS)) + imgType = 2; + if (safe_file_test (fname+".cust", Glib::FILE_TEST_EXISTS)) + imgType = 1; + else if (safe_file_test (fname+".jpg", Glib::FILE_TEST_EXISTS)) + imgType = 3; + + if (!imgType) + return false; + else if (imgType==1) { + FILE* f = safe_g_fopen (fname+".cust", "rb"); + if (!f) + return false; + int width, height; + fread (&width, 1, sizeof (int), f); + fread (&height, 1, sizeof (int), f); + unsigned char* tmpdata = new unsigned char [width*height*3]; + fread (tmpdata, width*height, 3, f); + fclose (f); + thumbImg = new Image16 (width, height); + int ix = 0, val; + for (int i=0; ir[i][j] = CLIP(val); + val = igammatab[tmpdata[ix++]]*256*8192/scaleForSave; + thumbImg->g[i][j] = CLIP(val); + val = igammatab[tmpdata[ix++]]*256*8192/scaleForSave; + thumbImg->b[i][j] = CLIP(val); + } + else { + val = tmpdata[ix++]*256*8192/scaleForSave; + thumbImg->r[i][j] = CLIP(val); + val = tmpdata[ix++]*256*8192/scaleForSave; + thumbImg->g[i][j] = CLIP(val); + val = tmpdata[ix++]*256*8192/scaleForSave; + thumbImg->b[i][j] = CLIP(val); + } + delete [] tmpdata; + return true; + } + else if (imgType==2) { + FILE* f = safe_g_fopen (fname+".cust16", "rb"); + if (!f) + return false; + int width, height; + fread (&width, 1, sizeof (int), f); + fread (&height, 1, sizeof (int), f); + thumbImg = new Image16 (width, height); + for (int i=0; ir[i], width, 2, f); + for (int i=0; ig[i], width, 2, f); + for (int i=0; ib[i], width, 2, f); + fclose (f); + return true; + } + else if (imgType==3) { + FILE* f = safe_g_fopen (fname+".jpg", "rb"); + if (!f) + return false; + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + cinfo.err = my_jpeg_std_error (&jerr); + jpeg_create_decompress (&cinfo); + my_jpeg_stdio_src (&cinfo,f); + if ( setjmp((reinterpret_cast(cinfo.src))->error_jmp_buf) == 0 ) + { + jpeg_read_header (&cinfo, TRUE); + int width, height; + width = cinfo.image_width; + height = cinfo.image_height; + cinfo.dct_method = JDCT_FASTEST; + cinfo.do_fancy_upsampling = 1; + jpeg_start_decompress(&cinfo); + thumbImg = new Image16 (width, height); + unsigned char* row = new unsigned char [width*3]; + while (cinfo.output_scanline < cinfo.output_height) { + jpeg_read_scanlines (&cinfo, &row, 1); + int ix = 0, val; + for (int j=0; jr[cinfo.output_scanline-1][j] = CLIP(val); + val = igammatab[row[ix++]]*256*8192/scaleForSave; + thumbImg->g[cinfo.output_scanline-1][j] = CLIP(val); + val = igammatab[row[ix++]]*256*8192/scaleForSave; + thumbImg->b[cinfo.output_scanline-1][j] = CLIP(val); + } + else { + val = row[ix++]*256*8192/scaleForSave; + thumbImg->r[cinfo.output_scanline-1][j] = CLIP(val); + val = row[ix++]*256*8192/scaleForSave; + thumbImg->g[cinfo.output_scanline-1][j] = CLIP(val); + val = row[ix++]*256*8192/scaleForSave; + thumbImg->b[cinfo.output_scanline-1][j] = CLIP(val); + } + } + } + jpeg_finish_decompress (&cinfo); + jpeg_destroy_decompress (&cinfo); + fclose (f); + delete [] row; + return true; + } + else { + fclose (f); + return false; + } + return true; + } + return false; +} + +bool Thumbnail::readData (const Glib::ustring& fname) { + + SafeKeyFile keyFile; + + try { + Glib::Mutex::Lock 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", "AutoWBTemp")) autowbTemp = keyFile.get_double ("LiveThumbData", "AutoWBTemp"); + if (keyFile.has_key ("LiveThumbData", "AutoWBGreen")) autowbGreen = keyFile.get_double ("LiveThumbData", "AutoWBGreen"); + 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++]; + } + } + } + catch (Glib::Error &err) { + return false; + } + + return true; +} + +bool Thumbnail::writeData (const Glib::ustring& fname) { + + SafeKeyFile keyFile; + + Glib::Mutex::Lock thmbLock(thumbMutex); + + try { + if( safe_file_test(fname,Glib::FILE_TEST_EXISTS) ) + keyFile.load_from_file (fname); + } catch (...) {} + + keyFile.set_double ("LiveThumbData", "CamWBRed", camwbRed); + keyFile.set_double ("LiveThumbData", "CamWBGreen", camwbGreen); + keyFile.set_double ("LiveThumbData", "CamWBBlue", camwbBlue); + keyFile.set_double ("LiveThumbData", "AutoWBTemp", autowbTemp); + keyFile.set_double ("LiveThumbData", "AutoWBGreen", autowbGreen); + 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) + 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..7a3c920e5 --- /dev/null +++ b/rtengine/rtthumbnail.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 _THUMBPROCESSINGPARAMETERS_ +#define _THUMBPROCESSINGPARAMETERS_ + +#include "rawmetadatalocation.h" +#include "procparams.h" +#include +#include +#include "image16.h" + +namespace rtengine { + + class Thumbnail { + + Glib::Mutex 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; + + Image16* thumbImg; + double camwbRed; + double camwbGreen; + double camwbBlue; + double autowbTemp; + double autowbGreen; + 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, 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, bool rotate); + static Thumbnail* loadFromImage (const Glib::ustring& fname, int &w, int &h, int fixwh, int deg=0); + + void getCamWB (double& temp, double& green); + void getAutoWB (double& temp, double& green); + 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); + }; +} + +#endif + diff --git a/rtengine/safegtk.cc b/rtengine/safegtk.cc new file mode 100644 index 000000000..c0cf1e4d3 --- /dev/null +++ b/rtengine/safegtk.cc @@ -0,0 +1,408 @@ +/* + * 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 +#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; +} + +#ifdef GLIBMM_EXCEPTIONS_ENABLED +# define SAFE_ENUMERATOR_CODE_START \ + do{try { if ((dirList = dir->enumerate_children ())) \ + for (Glib::RefPtr info = dirList->next_file(); info; info = dirList->next_file()) { + +# 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 = dirList->next_file(cancellable, error); !error.get() && info; info = dirList->next_file(cancellable, error)) { + +# 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 +} diff --git a/rtengine/safegtk.h b/rtengine/safegtk.h new file mode 100644 index 000000000..c9e832b00 --- /dev/null +++ b/rtengine/safegtk.h @@ -0,0 +1,44 @@ +#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(); +#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..f4c93ab40 --- /dev/null +++ b/rtengine/settings.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 _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 + Glib::ustring monitorProfile; ///< ICC profile of the monitor (full path recommended) + bool autoMonitorProfile; ///< Try to auto-determine the correct monitor color profile + + 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; // + bool gamutLch; + int protectred; + double protectredh; + + /** 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..28bd1a1da --- /dev/null +++ b/rtengine/shmap.cc @@ -0,0 +1,220 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#include "shmap.h" +#include "gauss.h" +#include "bilateral2.h" +#include "rtengine.h" +#include "rt_math.h" +#include "rawimagesource.h" + +#undef THREAD_PRIORITY_NORMAL + +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) { + AlignedBufferMP* pBuffer = new AlignedBufferMP (max(W,H)); + gaussHorizontal (map, map, *pBuffer, W, H, radius); + gaussVertical (map, map, *pBuffer, W, H, radius); + delete pBuffer; + } + else { +/* +#if 0 +// the new OpenMP method does not need thread number specific code. +// #ifdef _OPENMP + #pragma omp parallel if (multiThread) + { + int tid = omp_get_thread_num(); + int nthreads = omp_get_num_threads(); + int blk = H/nthreads; + + if (tid (map, buffer, W, H, 8000, radius, tid*blk, (tid+1)*blk); + else + bilateral (map, buffer, W, H, 8000, radius, tid*blk, H); + } +#else + bilateral (map, buffer, W, H, 8000, radius, 0, H); +#endif +*/ + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //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(exp(-(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 = 1.0/n * val + (1.0 - 1.0/n) * _avg; + n++; + } + avg = (int) _avg; +} + +void SHMap::forceStat (float max_, float min_, float avg_) { + + max_f = max_; + min_f = min_; + avg = avg_; +} + + +void SHMap::dirpyr_shmap(float ** data_fine, float ** data_coarse, int width, int height, LUTf & rangefn, int level, int scale) +{ + //scale is spacing of directional averaging weights + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // calculate weights, compute directionally weighted average + + int halfwin=2; + 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}}; + + //generate domain kernel + if (level<2) { + halfwin = 1; + domker[1][1]=domker[1][2]=domker[2][1]=domker[2][2]=1; + } + + + int scalewin = halfwin*scale; + +#ifdef _OPENMP +#pragma omp parallel for +#endif + for(int i = 0; i < height; i++) { + for(int j = 0; j < width; j++) + { + float val=0; + float norm=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; + float dirwt = ( domker[(inbr-i)/scale+halfwin][(jnbr-j)/scale+halfwin] * rangefn[abs(data_fine[inbr][jnbr]-data_fine[i][j])] ); + val += dirwt*data_fine[inbr][jnbr]; + norm += dirwt; + /*if (val<0 || norm<0) { + printf("val=%f norm=%f \n",val,norm); + printf("i=%d j=%d inbr=%d jnbr=%d domker=%d val=%d nbrval=%d rangefn=%d \n",i,j,inbr,jnbr, \ + domker[(inbr-i)/scale+halfwin][(jnbr-j)/scale+halfwin], \ + data_fine[i][j], data_fine[inbr][jnbr], \ + rangefn[abs(data_fine[inbr][jnbr]-data_fine[i][j])]); + }*/ + } + } + data_coarse[i][j] = val/norm; // low pass filter + /*if (val<=0 || norm<=0) + printf("val=%f norm=%f \n",val,norm); */ + } + } + +} + + +}//end of SHMap diff --git a/rtengine/shmap.h b/rtengine/shmap.h new file mode 100644 index 000000000..f352b0f82 --- /dev/null +++ b/rtengine/shmap.h @@ -0,0 +1,44 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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..359a818db --- /dev/null +++ b/rtengine/simpleprocess.cc @@ -0,0 +1,568 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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" +#undef THREAD_PRIORITY_NORMAL + +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; + } + } + + ImProcFunctions ipf (¶ms, true); + + PreviewProps pp (0, 0, fw, fh, 1); + imgsrc->preprocess( params.raw, params.lensProf, params.coarse); + if (pl) pl->setProgress (0.20); + imgsrc->demosaic( params.raw); + if (pl) pl->setProgress (0.30); + imgsrc->HLRecovery_Global( params.hlrecovery ); + if (pl) pl->setProgress (0.40); + // set the color temperature + ColorTemp currWB = ColorTemp (params.wb.temperature, params.wb.green, params.wb.method); + if (params.wb.method=="Camera") + currWB = imgsrc->getWB (); + else if (params.wb.method=="Auto") + currWB = imgsrc->getAutoWB (); + Imagefloat* baseImg = new Imagefloat (fw, fh); + imgsrc->getImage (currWB, tr, baseImg, pp, params.hlrecovery, params.icm, params.raw); + if (pl) pl->setProgress (0.45); + + // perform luma/chroma denoise + LabImage* labView = new LabImage (fw,fh); + if (params.dirpyrDenoise.enabled) { + ipf.RGB_denoise(baseImg, baseImg, imgsrc->isRAW(), params.dirpyrDenoise, params.defringe); + } + imgsrc->convertColorSpace(baseImg, params.icm, params.raw); + + // perform first analysis + LUTu hist16 (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, 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 rCurve (65536,0); + LUTf gCurve (65536,0); + LUTf bCurve (65536,0); + LUTu dummy; + + ToneCurve customToneCurve1, customToneCurve2; + + 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); + + ipf.rgbProc (baseImg, labView, curve1, curve2, curve, shmap, params.toneCurve.saturation, rCurve, gCurve, bCurve, customToneCurve1, customToneCurve2, expcomp, hlcompr, hlcomprthresh); + + // 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...??? + + // luminance histogram update + hist16.clear(); + for (int i=0; iL[i][j])))]++; + + // luminance processing + + ipf.EPDToneMap(labView); + bool utili=false; + bool autili=false; + bool butili=false; + bool ccutili=false; + bool cclutili=false; + CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, hist16, hist16, curve, dummy, 1, utili); + + 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, 1); + //ipf.luminanceCurve (labView, labView, curve); + ipf.chromiLuminanceCurve (labView, labView, curve1, curve2, satcurve,lhskcurve,curve, utili, autili, butili, ccutili,cclutili); + ipf.vibrance(labView); + + ipf.impulsedenoise (labView); + ipf.defringe (labView); + if (params.sharpenEdge.enabled) { + ipf.MLsharpen(labView); + } + if (params.sharpenMicro.enabled) { + ipf.MLmicrocontrast (labView); + } + if (params.sharpening.enabled) { + float** buffer = new float*[fh]; + 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]; + 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"); + + + } + } + } + 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); + } + } + + if (!job->initialImage) + ii->decreaseRef (); + + delete job; + if (pl) + pl->setProgress (0.75); + + 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 ("Can not load input image."); + currentJob = bpl->imageReady (img); + } +} + +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/slicer.cc b/rtengine/slicer.cc new file mode 100644 index 000000000..0a3eafece --- /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((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 100644 index 000000000..6ce81ba22 --- /dev/null +++ b/rtengine/stdimagesource.cc @@ -0,0 +1,552 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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 "curves.h" +#include "color.h" + +#undef THREAD_PRIORITY_NORMAL + +namespace rtengine { + +extern const Settings* settings; + +template void freeArray (T** a, int H) { + for (int i=0; i T** allocArray (int W, int H) { + + T** t = new T*[H]; + for (int i=0; iheight/HR_SCALE; + freeArray(hrmap[0], dh); + freeArray(hrmap[1], dh); + freeArray(hrmap[2], dh); + } + + delete img; + + if (needhr) + freeArray(needhr, img->height); +} + +int StdImageSource::load (Glib::ustring fname, bool batch) { + + fileName = fname; + + img = new Image16 (); + if (plistener) { + plistener->setProgressStr ("PROGRESSBAR_LOADING"); + plistener->setProgress (0.0); + img->setProgressListener (plistener); + } + + 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) { + Image16* rot = img->rotate(deg); + delete img; + img = rot; + } + } + + if (plistener) { + plistener->setProgressStr ("PROGRESSBAR_READY"); + plistener->setProgress (1.0); + } + + wb = ColorTemp (1.0,1.0,1.0); + //this is probably a mistake if embedded profile is not D65 + + return 0; +} + +void StdImageSource::transform (PreviewProps pp, int tran, int &sx1, int &sy1, int &sx2, int &sy2) { + + int W = img->width; + int H = img->height; + int sw = W, sh = H; + if ((tran & TR_ROT) == TR_R90 || (tran & TR_ROT) == TR_R270) { + sw = H; + sh = W; + } + 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 = W - ppx - pp.w; + sy1 = H - ppy - pp.h; + sx2 = sx1 + pp.w; + sy2 = sy1 + pp.h; + } + else if ((tran & TR_ROT) == TR_R90) { + sx1 = ppy; + sy1 = H - ppx - pp.w; + sx2 = sx1 + pp.h; + sy2 = sy1 + pp.w; + } + else if ((tran & TR_ROT) == TR_R270) { + sx1 = W - 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; +} + +void StdImageSource::getImage_ (ColorTemp ctemp, int tran, Imagefloat* image, PreviewProps pp, bool first, HRecParams 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); + // printf(" sx1:%d sy1:%d sx2:%d sy2:%d\n",sx1, sy1, sx2, sy2); +/* the sizes are already known: image->width and image->height + int imwidth = (sx2 - sx1) / pp.skip + ((sx2 - sx1) % pp.skip > 0); + int imheight = (sy2 - sy1) / pp.skip + ((sy2 - sy1) % pp.skip > 0); +*/ + int imwidth=image->width,imheight=image->height; + // printf("1: imw=%d imh=%d\n",imwidth,imheight); + if (((tran & TR_ROT) == TR_R90)||((tran & TR_ROT) == TR_R270)) + { + int swap = imwidth; + imwidth=imheight; + imheight=swap; + } + // printf("2: imw=%d imh=%d\n",imwidth,imheight); + int istart = sy1; + int maxx=img->width,maxy=img->height; + int mtran = tran; + 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; + rm/=area; + gm/=area; + bm/=area; + +#ifdef _OPENMP +#pragma omp parallel + { +#endif + float *line_red = new float[imwidth]; + float *line_green = new float[imwidth]; + float *line_blue = new float[imwidth]; + +#ifdef _OPENMP +#pragma omp for +#endif + for (int ix=0;ix=maxy-skip) i=maxy-skip-1; // avoid trouble + 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; mr[i+m][jx+n]); + gtot += Color::igamma_srgb(img->g[i+m][jx+n]); + btot += Color::igamma_srgb(img->b[i+m][jx+n]); + } + line_red[j] = rtot; + line_green[j] = gtot; + line_blue[j] = btot; + } + + // covert back to gamma and clip +#define GCLIP( x ) Color::gamma_srgb(CLIP(x)) + + if ((mtran & TR_ROT) == TR_R180) + for (int j=0; jr[imheight-1-ix][imwidth-1-j] = GCLIP(rm*line_red[j])/65535.0; + image->g[imheight-1-ix][imwidth-1-j] = GCLIP(gm*line_green[j])/65535.0; + image->b[imheight-1-ix][imwidth-1-j] = GCLIP(bm*line_blue[j])/65535.0; + } + else if ((mtran & TR_ROT) == TR_R90) + for (int j=0,jx=sx1; jr[j][imheight-1-ix] = GCLIP(rm*line_red[j])/65535.0; + image->g[j][imheight-1-ix] = GCLIP(gm*line_green[j])/65535.0; + image->b[j][imheight-1-ix] = GCLIP(bm*line_blue[j])/65535.0; + } + else if ((mtran & TR_ROT) == TR_R270) + for (int j=0,jx=sx1; jr[imwidth-1-j][ix] = GCLIP(rm*line_red[j])/65535.0; + image->g[imwidth-1-j][ix] = GCLIP(gm*line_green[j])/65535.0; + image->b[imwidth-1-j][ix] = GCLIP(bm*line_blue[j])/65535.0; + } + else { + for (int j=0,jx=sx1; jr[ix][j] = GCLIP(rm*line_red[j])/65535.0; + image->g[ix][j] = GCLIP(gm*line_green[j])/65535.0; + image->b[ix][j] = GCLIP(bm*line_blue[j])/65535.0; + //if (ix==100 && j==100) printf("stdimsrc before R= %f G= %f B= %f \n",65535*image->r[ix][j],65535*image->g[ix][j],65535*image->b[ix][j]); + + } + } + } +#undef GCLIP + delete [] line_red; + delete [] line_green; + delete [] line_blue; +#ifdef _OPENMP + } +#endif +} + + +void StdImageSource::getImage (ColorTemp ctemp, int tran, Imagefloat* image, PreviewProps pp, HRecParams hrp, ColorManagementParams cmp, RAWParams raw) { + + MyTime t1,t2; + + t1.set (); + + // the code will use OpenMP as of now. + + //Image16* tmpim = new Image16 (image->width,image->height); + getImage_ (ctemp, tran, image, pp, true, hrp); + + // *** colorSpaceConversion was there *** +/* colorSpaceConversion (image, cmp, embProfile); + + for ( int h = 0; h < image->height; ++h ) + for ( int w = 0; w < image->width; ++w ) { + image->r[h][w] *= 65535.0f; + image->g[h][w] *= 65535.0f; + image->b[h][w] *= 65535.0f; + //if (h==100 && w==100) printf("stdimsrc after R= %f G= %f B= %f \n",image->r[h][w],image->g[h][w],image->b[h][w]); + } +*/ + // Flip if needed + if (tran & TR_HFLIP) + hflip (image); + if (tran & TR_VFLIP) + vflip (image); + + t2.set (); +} + +void StdImageSource::convertColorSpace(Imagefloat* image, ColorManagementParams cmp, RAWParams raw) { + colorSpaceConversion (image, cmp, embProfile); +} + +void StdImageSource::colorSpaceConversion (Imagefloat* im, ColorManagementParams cmp, cmsHPROFILE embedded) { + + cmsHPROFILE in; + cmsHPROFILE out = iccStore->workingSpace (cmp.working); + if (cmp.input=="(embedded)" || cmp.input=="" || cmp.input=="(camera)") { + if (embedded) + in = embedded; + else + in = iccStore->getsRGBProfile (); + } else { + if (cmp.input!="(none)") { + in = iccStore->getProfile (cmp.input); + if (in==NULL && embedded) + in = embedded; + else if (in==NULL) + in = iccStore->getsRGBProfile (); + } + } + + if (cmp.input!="(none)") { + lcmsMutex->lock (); + cmsHTRANSFORM hTransform = cmsCreateTransform (in, TYPE_RGB_FLT, out, TYPE_RGB_FLT, settings->colorimetricIntent, + cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); + lcmsMutex->unlock (); + + im->ExecCMSTransform(hTransform); + + cmsDeleteTransform(hTransform); + } + + // Code moved from getImage to change the range of the float value from [0.;1.] to [0.;65535.] + for ( int h = 0; h < im->height; ++h ) + for ( int w = 0; w < im->width; ++w ) { + im->r[h][w] *= 65535.0f; + im->g[h][w] *= 65535.0f; + im->b[h][w] *= 65535.0f; + //if (h==100 && w==100) printf("stdimsrc after R= %f G= %f B= %f \n",im->r[h][w],im->g[h][w],im->b[h][w]); + } +} + + +void StdImageSource::colorSpaceConversion16 (Image16* im, ColorManagementParams cmp, cmsHPROFILE embedded) { + + cmsHPROFILE in; + cmsHPROFILE out = iccStore->workingSpace (cmp.working); + if (cmp.input=="(embedded)" || cmp.input=="" || cmp.input=="(camera)") { + if (embedded) + in = embedded; + else + in = iccStore->getsRGBProfile (); + } + else if (cmp.input!="(none)") { + in = iccStore->getProfile (cmp.input); + if (in==NULL && embedded) + in = embedded; + else if (in==NULL) + in = iccStore->getsRGBProfile (); + } + + if (cmp.input!="(none)") { + lcmsMutex->lock (); + cmsHTRANSFORM hTransform = cmsCreateTransform (in, TYPE_RGB_16, out, TYPE_RGB_16, settings->colorimetricIntent, + cmsFLAGS_NOCACHE); + lcmsMutex->unlock (); + + im->ExecCMSTransform(hTransform); + + cmsDeleteTransform(hTransform); + } + + // WARNING: A range update may be missing here (see colorSpaceConversion above) +} + +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::hflip (Imagefloat* image) { + int width = image->width; + int height = image->height; + + float* rowr = new float[width]; + float* rowg = new float[width]; + float* rowb = new float[width]; + for (int i=0; ir[i][width-1-j]; + rowg[j] = image->g[i][width-1-j]; + rowb[j] = image->b[i][width-1-j]; + } + memcpy (image->r[i], rowr, width*sizeof(float)); + memcpy (image->g[i], rowg, width*sizeof(float)); + memcpy (image->b[i], rowb, width*sizeof(float)); + } + delete [] rowr; + delete [] rowg; + delete [] rowb; +} + +void StdImageSource::vflip (Imagefloat* image) { + int width = image->width; + int height = image->height; + + float tmp; + for (int i=0; ir[i][j]; + image->r[i][j] = image->r[height-1-i][j]; + image->r[height-1-i][j] = tmp; + tmp = image->g[i][j]; + image->g[i][j] = image->g[height-1-i][j]; + image->g[height-1-i][j] = tmp; + tmp = image->b[i][j]; + image->b[i][j] = image->b[height-1-i][j]; + image->b[height-1-i][j] = tmp; + } +} + +void StdImageSource::getAutoExpHistogram (LUTu & histogram, int& histcompr) { + + histcompr = 3; + + histogram(65536>>histcompr); + histogram.clear(); + + for (int i=0; iheight; i++) + for (int j=0; jwidth; j++) { + histogram[(int)Color::igamma_srgb (img->r[i][j])>>histcompr]++; + histogram[(int)Color::igamma_srgb (img->g[i][j])>>histcompr]++; + histogram[(int)Color::igamma_srgb (img->b[i][j])>>histcompr]++; + } +} + +ColorTemp StdImageSource::getAutoWB () { + + double avg_r = 0; + double avg_g = 0; + double avg_b = 0; + int n = 0; + //int p = 6; + + for (int i=1; iheight-1; i++) + for (int j=1; jwidth-1; j++) { + if (img->r[i][j]>64000 || img->g[i][j]>64000 || img->b[i][j]>64000) + continue; + avg_r += SQR((double)img->r[i][j]); + avg_g += SQR((double)img->g[i][j]); + avg_b += SQR((double)img->b[i][j]); + /*avg_r += intpow((double)img->r[i][j], p); + avg_g += intpow((double)img->g[i][j], p); + avg_b += intpow((double)img->b[i][j], p);*/ + + n++; + } + return ColorTemp (sqrt(avg_r/n), sqrt(avg_g/n), sqrt(avg_b/n)); + //return ColorTemp (pow(avg_r/n, 1.0/p), pow(avg_g/n, 1.0/p), pow(avg_b/n, 1.0/p)); +} + +void StdImageSource::transformPixel (int x, int y, int tran, int& tx, int& ty) { + + int W = img->width; + int H = img->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; + } +} + +ColorTemp StdImageSource::getSpotWB (std::vector red, std::vector green, std::vector& blue, int tran) { + + int x; int y; + double reds = 0, greens = 0, blues = 0; + int rn = 0, gn = 0, bn = 0; + for (size_t i=0; i=0 && y>=0 && xwidth && yheight) { + reds += img->r[y][x]; +// img->r[y][x]=0; // debug!!! + rn++; + } + transformPixel (green[i].x, green[i].y, tran, x, y); + if (x>=0 && y>=0 && xwidth && yheight) { + greens += img->g[y][x]; +// img->g[y][x]=0; // debug!!! + gn++; + } + transformPixel (blue[i].x, blue[i].y, tran, x, y); + if (x>=0 && y>=0 && xwidth && yheight) { + blues += img->b[y][x]; +// img->b[y][x]=0; // debug!!! + bn++; + } + } + double img_r, img_g, img_b; + wb.getMultipliers (img_r, img_g, img_b); + 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); +} +} + diff --git a/rtengine/stdimagesource.h b/rtengine/stdimagesource.h new file mode 100644 index 000000000..25eb71cde --- /dev/null +++ b/rtengine/stdimagesource.h @@ -0,0 +1,78 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#ifndef _STDIMAGESOURCE_ +#define _STDIMAGESOURCE_ + +#include "imagesource.h" + +namespace rtengine { + +class StdImageSource : public ImageSource { + + protected: + Image16* img; + ColorTemp wb; + ProgressListener* plistener; + bool full; + float** hrmap[3]; + char** needhr; + int max[3]; + + void transform (PreviewProps pp, int tran, int &sx1, int &sy1, int &sx2, int &sy2); + void transformPixel (int x, int y, int tran, int& tx, int& ty); + bool rgbSourceModified; + public: + StdImageSource (); + ~StdImageSource (); + + int load (Glib::ustring fname, bool batch = false); + void getImage (ColorTemp ctemp, int tran, Imagefloat* image, PreviewProps pp, HRecParams hrp, ColorManagementParams cmp, RAWParams raw); + ColorTemp getWB () { return wb; } + ColorTemp getAutoWB (); + ColorTemp getSpotWB (std::vector red, std::vector green, std::vector& blue, int tran); + 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; } + ImageMatrices* getImageMatrices () { return (ImageMatrices*)NULL; } + bool isRAW() const { return false; } + + void setProgressListener (ProgressListener* pl) { plistener = pl; } + + void convertColorSpace(Imagefloat* image, ColorManagementParams cmp, RAWParams raw);// RAWParams raw will not be used for non-raw files (see imagesource.h) + static void colorSpaceConversion (Imagefloat* im, ColorManagementParams cmp, cmsHPROFILE embedded); + 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..7e753c3f0 --- /dev/null +++ b/rtexif/CMakeLists.txt @@ -0,0 +1,21 @@ +add_library (rtexif rtexif.cc stdattribs.cc nikonattribs.cc canonattribs.cc + pentaxattribs.cc fujiattribs.cc sonyminoltaattribs.cc olympusattribs.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) + +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..faf0bcd5a --- /dev/null +++ b/rtexif/canonattribs.cc @@ -0,0 +1,1459 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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 () { + 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, "Sigma 28-80mm f/3.5-5.6 II Macro")); + choices.insert(p_t(6, "Tokina AF 193-2 19-35mm f/3.5-4.5")); + 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-X242AF 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(11, "Canon EF 35mm f/2")); + choices.insert(p_t(13, "Canon EF 15mm f/2.8")); + 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-X280AF 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 Ultron 40mm f/2 SLII Aspherical")); + 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")); + 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(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(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(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")); + 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 APO 50-500mm f/4-6.3 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(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(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 50mm f/1.4 EX DG HSM")); + choices.insert(p_t(169, "Sigma 85mm f/1.4 EX 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 APO 70-200mm f/2.8 EX 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 USM")); + 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(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")); + 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")); + 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")); + choices.insert(p_t(214, "Canon EF-S 18-55mm f/3.5-4.5 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 USM")); + choices.insert(p_t(225, "Canon EF 70-200mm f/2.8L IS USM + x1.4")); + choices.insert(p_t(226, "Canon EF 70-200mm f/2.8L IS USM + x2")); + choices.insert(p_t(227, "Canon EF 70-200mm f/2.8L IS + 2.8x")); + 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 USM")); + 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 USM")); + choices.insert(p_t(242, "Canon EF 70-200mm f/4L IS USM")); + 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(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")); + } + + 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[1024]; + sprintf (buffer, "%.0f", pow (2, t->toInt()/32.0 - 4) * 50 ); + return buffer; + } +}; +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, 1, 0, 0, 1, "MacroMode", &caMacroModeInterpreter}, + {0, 1, 0, 0, 2, "SelfTimer", &caSelfTimerInterpreter}, + {0, 1, 0, 0, 3, "Quality", &caQualityInterpreter}, + {0, 1, 0, 0, 4, "CanonFlashMode", &caFlashModeInterpreter}, + {0, 1, 0, 0, 5, "ContinuousDrive", &caContinuousDriveInterpreter}, + {0, 1, 0, 0, 7, "FocusMode", &caFocusModeInterpreter}, + {0, 1, 0, 0, 9, "RecordMode", &caRecordModeInterpreter}, + {0, 1, 0, 0, 10, "CanonImageSize", &caImageSizeInterpreter}, + {0, 1, 0, 0, 11, "EasyMode", &caEasyModeInterpreter}, + {0, 1, 0, 0, 12, "DigitalZoom", &caDigitalZoomInterpreter}, + {0, 1, 0, 0, 13, "Contrast", &stdInterpreter}, + {0, 1, 0, 0, 14, "Saturation", &stdInterpreter}, + {0, 1, 0, 0, 15, "Sharpness", &stdInterpreter}, + {0, 1, 0, 0, 16, "CameraISO", &stdInterpreter}, + {0, 1, 0, 0, 17, "MeteringMode", &caMeteringModeInterpreter}, + {0, 1, 0, 0, 18, "FocusRange", &caFocusRangeInterpreter}, + {0, 1, 0, 0, 19, "AFPoint", &caAFPointInterpreter}, + {0, 1, 0, 0, 20, "CanonExposureMode", &caExposureModeInterpreter}, + {0, 1, 0, 0, 22, "LensID", &caLensInterpreter}, + {0, 1, 0, 0, 23, "LongFocal", &caFocalInterpreter}, + {0, 1, 0, 0, 24, "ShortFocal", &caFocalInterpreter}, + {0, 1, 0, 0, 25, "FocalUnits", &stdInterpreter}, + {0, 1, 0, 0, 26, "MaxAperture", &caApertureInterpreter}, + {0, 1, 0, 0, 27, "MinAperture", &caApertureInterpreter}, + {0, 1, 0, 0, 28, "FlashActivity", &stdInterpreter}, + {0, 1, 0, 0, 29, "FlashBits", &caFlashBitsInterpreter}, + {0, 1, 0, 0, 32, "FocusContinuous", &caFocusContinuousInterpreter}, + {0, 1, 0, 0, 33, "AESetting", &caAESettingsInterpreter}, + {0, 1, 0, 0, 34, "ImageStabilization", &caStabilizationInterpreter}, + {0, 1, 0, 0, 35, "DisplayAperture", &stdInterpreter}, + {0, 1, 0, 0, 36, "ZoomSourceWidth", &stdInterpreter}, + {0, 1, 0, 0, 37, "ZoomTargetWidth", &stdInterpreter}, + {0, 1, 0, 0, 39, "SpotMeteringMode", &caSpotMeteringInterpreter}, + {0, 1, 0, 0, 40, "PhotoEffect", &caPhotoEffectInterpreter}, + {0, 1, 0, 0, 41, "ManualFlashOutput", &caManualFlashInterpreter}, + {0, 1, 0, 0, 42, "ColorTone", &stdInterpreter}, + {0, 1, 0, 0, 46, "SRAWQuality", &caRAWQualityInterpreter}, + {-1, 0, 0, 0, 0, "", NULL} +}; + +const TagAttrib canonFocalLengthAttribs[] = { + {0, 1, 0, 0, 0, "FocalType", &caFocalTypeInterpreter}, + {0, 1, 0, 0, 1, "FocalLength", &caFocalInterpreter}, + {0, 1, 0, 0, 2, "FocalPlaneXSize", &caFocalPlaneInterpreter}, + {0, 1, 0, 0, 3, "FocalPlaneYSize", &caFocalPlaneInterpreter}, + {-1, 0, 0, 0, 0, "", NULL} +}; + +const TagAttrib canonShotInfoAttribs[] = { + {0, 1, 0, 0, 1, "AutoISO", &stdInterpreter}, + {0, 1, 0, 0, 2, "BaseISO" ,&caBaseISOInterpreter}, + {0, 1, 0, 0, 3, "MeasuredEV", &stdInterpreter}, + {0, 1, 0, 0, 4, "TargetAperture", &caApertureInterpreter}, + {0, 1, 0, 0, 5, "TargetExposureTime",&caExposureTimeInterpreter}, + {0, 1, 0, 0, 6, "ExposureCompensation",&caEVInterpreter}, + {0, 1, 0, 0, 7, "WhiteBalance",&caWhiteBalanceInterpreter}, + {0, 1, 0, 0, 8, "SlowShutter",&caSlowShutterInterpreter}, + {0, 1, 0, 0, 9, "SequenceNumber", &stdInterpreter}, + {0, 1, 0, 0,10, "OpticalZoomCode", &stdInterpreter}, + {0, 1, 0, 0,13, "FlashGuideNumber" , &caFlashGuideNumberInterpreter}, + {0, 1, 0, 0,14, "AFPointsInFocus", &caAFPointsInFocusInterpreter}, + {0, 1, 0, 0,15, "FlashExposureComp", &stdInterpreter}, + {0, 1, 0, 0,16, "AutoExposureBracketing",&caAutoExposureBracketingInterpreter}, + {0, 1, 0, 0,17, "AEBBracketValue", &stdInterpreter}, + {0, 1, 0, 0,18, "ControlMode", &caControModeInterpreter}, + {0, 1, 0, 0,19, "FocusDistanceUpper", &caFocusDistanceInterpreter}, + {0, 1, 0, 0,20, "FocusDistanceLower", &caFocusDistanceInterpreter}, + {0, 1, 0, 0,21, "FNumber" ,&caApertureInterpreter}, + {0, 1, 0, 0,22, "ExposureTime",&caExposureTimeInterpreter}, + {0, 1, 0, 0,24, "BulbDuration", &stdInterpreter}, + {0, 1, 0, 0,24, "MeasuredEV2", &caMeasuredEVInterpreter}, + {0, 1, 0, 0,26, "CameraType", &caCameraTypeInterpreter}, + {0, 1, 0, 0,27, "AutoRotate",&caAutoRotateInterpreter}, + {0, 1, 0, 0,28, "NDFilter",&caOnOffInterpreter}, + {0, 1, 0, 0,29, "Self-timer2", &stdInterpreter}, + {0, 1, 0, 0,33, "FlashOutput", &stdInterpreter}, + {-1, 0, 0, 0, 0, "", NULL}, +}; + +const TagAttrib canonFileInfoAttribs[] = { + {0, 1, 0, 0, 1, "FileNumber", &caFileNumberInterpreter}, + {0, 1, 0, 0, 3, "BracketMode", &caBracketModeInterpreter}, + {0, 1, 0, 0, 4, "BracketValue", &stdInterpreter}, + {0, 1, 0, 0, 5, "BracketShotNumber", &stdInterpreter}, + {0, 1, 0, 0, 6, "RawJpgQuality",&caRAWJpegQualityInterpreter}, + {0, 1, 0, 0, 7, "RawJpgSize",&caJpegSizeInterpreter}, + {0, 1, 0, 0, 8, "NoiseReduction",&stdInterpreter}, + {0, 1, 0, 0, 9, "WBBracketMode" ,&caWBBracketModeInterpreter}, + {0, 1, 0, 0,12, "WBBracketValueAB", &stdInterpreter}, + {0, 1, 0, 0,13, "WBBracketValueGM", &stdInterpreter}, + {0, 1, 0, 0,14, "FilterEffect" ,&caFilterEffectInterpreter}, + {0, 1, 0, 0,15, "ToningEffect" ,&caToningEffectInterpreter}, + {0, 1, 0, 0,19, "LiveViewShooting" ,&caOnOffInterpreter}, + {0, 1, 0, 0,25, "FlashExposureLock" ,&caOnOffInterpreter}, + {-1,0, 0, 0, 0, "", NULL}, +}; + +const TagAttrib canonProcessingInfoAttribs[] = { + {0, 1, 0, 0, 1,"ToneCurve", &caToneCurveInterpreter}, + {0, 1, 0, 0, 2,"Sharpness", &stdInterpreter}, + {0, 1, 0, 0, 3,"SharpnessFrequency", &caSharpnessFrequencyInterpreter}, + {0, 1, 0, 0, 4,"SensorRedLevel", &stdInterpreter}, + {0, 1, 0, 0, 5,"SensorBlueLevel", &stdInterpreter}, + {0, 1, 0, 0, 6,"WhiteBalanceRed", &stdInterpreter}, + {0, 1, 0, 0, 7,"WhiteBalanceBlue", &stdInterpreter}, + {0, 1, 0, 0, 8,"WhiteBalance", &caWhiteBalanceInterpreter}, + {0, 1, 0, 0, 9,"ColorTemperature", &stdInterpreter}, + {0, 1, 0, 0,10,"PictureStyle", &caPictureStyleInterpreter}, + {0, 1, 0, 0,11,"DigitalGain", &stdInterpreter}, + {0, 1, 0, 0,12,"WBShiftAB", &stdInterpreter}, + {0, 1, 0, 0,13,"WBShiftGM", &stdInterpreter}, + {-1,0, 0, 0, 0, "", NULL}, +}; + +const TagAttrib canonPanoramaInfoAttribs[] = { + {0, 1, 0, 0, 2,"PanoramaFrameNumber", &stdInterpreter}, + {0, 1, 0, 0, 5,"PanoramaDirection", &caPanoramaDirectionInterpreter}, + {-1,0, 0, 0, 0, "", NULL}, +}; + +const TagAttrib canonCropInfoAttribs[] = { + {0, 1, 0, 0, 0,"CropLeftMargin", &stdInterpreter}, + {0, 1, 0, 0, 1,"CropRightMargin", &stdInterpreter}, + {0, 1, 0, 0, 2,"CropTopMargin", &stdInterpreter}, + {0, 1, 0, 0, 3,"CropBottomMargin", &stdInterpreter}, + {-1,0, 0, 0, 0, "", NULL}, +}; + +const TagAttrib canonAspectInfoAttribs[] = { + {0, 1, 0, 0, 0,"AspectRatio", &caAspectRatioInterpreter}, + {0, 1, 0, 0, 1,"CroppedImageWidth", &stdInterpreter}, + {0, 1, 0, 0, 2,"CroppedImageHeight", &stdInterpreter}, + {-1,0, 0, 0, 0, "", NULL}, +}; + +const TagAttrib canonMicroAdjustAttrib[] = { + {0, 1, 0, 0, 1,"AFMicroAdjActive", &caOnOffInterpreter}, + {-1,0, 0, 0, 2,"AFMicroAdjValue", &stdInterpreter}, +}; + +const TagAttrib canonAttribs[] = { + {0, 1, 0, canonCameraSettingsAttribs, 0x0001, "CanonCameraSettings", &stdInterpreter}, + {0, 1, 0, canonFocalLengthAttribs, 0x0002, "CanonFocalLength", &stdInterpreter}, + {0, 1, 0, 0, 0x0003, "CanonFlashInfo", &stdInterpreter}, + {0, 1, 0, canonShotInfoAttribs, 0x0004, "CanonShotInfo", &stdInterpreter}, + {0, 1, 0, canonPanoramaInfoAttribs, 0x0005, "CanonPanorama", &stdInterpreter}, + {0, 1, 0, 0, 0x0006, "CanonImageType", &stdInterpreter}, + {0, 1, 0, 0, 0x0007, "CanonFirmwareVersion", &stdInterpreter}, + {0, 1, 0, 0, 0x0008, "FileNumber", &stdInterpreter}, + {0, 1, 0, 0, 0x0009, "OwnerName", &stdInterpreter}, + {0, 1, 0, 0, 0x000a, "ColorInfoD30", &stdInterpreter}, + {0, 1, 0, 0, 0x000c, "SerialNumber", &stdInterpreter}, + {0, 1, 0, 0, 0x000d, "CanonCameraInfo", &stdInterpreter}, + {0, 1, 0, 0, 0x000e, "CanonFileLength", &stdInterpreter}, + {0, 1, 0, 0, 0x000f, "CustomFunctions", &stdInterpreter}, + {0, 1, 0, 0, 0x0010, "CanonModelID", &caModelIDInterpreter}, + {0, 1, 0, 0, 0x0012, "CanonAFInfo", &stdInterpreter}, + {0, 1, 0, 0, 0x0015, "SerialNumberFormat", &stdInterpreter}, + {0, 1, 0, 0, 0x001c, "DateStampMode", &stdInterpreter}, + {0, 1, 0, 0, 0x001d, "MyColors", &stdInterpreter}, + {0, 1, 0, 0, 0x001e, "FirmwareRevision", &stdInterpreter}, + {0, 3, 0, 0, 0x0024, "FaceDetect1", &stdInterpreter}, + {0, 3, 0, 0, 0x0025, "FaceDetect2", &stdInterpreter}, + {0, 1, 0, 0, 0x0026, "CanonAFInfo2", &stdInterpreter}, + {0, 1, 0, 0, 0x0083, "OriginalDecisionData", &stdInterpreter}, + {0, 1, 0, 0, 0x0090, "CustomFunctions1D", &stdInterpreter}, + {0, 1, 0, 0, 0x0091, "PersonalFunctions", &stdInterpreter}, + {0, 1, 0, 0, 0x0092, "PersonalFunctionValues", &stdInterpreter}, + {0, 1, 0, canonFileInfoAttribs, 0x0093, "CanonFileInfo", &stdInterpreter}, + {0, 1, 0, 0, 0x0094, "AFPointsInFocus1D", &stdInterpreter}, + {0, 1, 0, 0, 0x0095, "LensType", &stdInterpreter}, + {0, 1, 0, 0, 0x0096, "InternalSerialNumber", &caIntSerNumInterpreter}, + {0, 1, 0, 0, 0x0097, "DustRemovalData", &stdInterpreter}, + {0, 1, 0, canonCropInfoAttribs, 0x0098, "CropInfo", &stdInterpreter}, + {0, 1, 0, 0, 0x0099, "CustomFunctions2", &stdInterpreter}, + {0, 1, 0, canonAspectInfoAttribs, 0x009a, "AspectInfo", &stdInterpreter}, + {0, 1, 0, canonProcessingInfoAttribs, 0x00a0, "ProcessingInfo", &stdInterpreter}, + {0, 1, 0, 0, 0x00a1, "ToneCurveTable", &stdInterpreter}, + {0, 1, 0, 0, 0x00a2, "SharpnessTable", &stdInterpreter}, + {0, 1, 0, 0, 0x00a3, "SharpnessFreqTable", &stdInterpreter}, + {0, 1, 0, 0, 0x00a4, "WhiteBalanceTable", &stdInterpreter}, + {0, 1, 0, 0, 0x00a9, "ColorBalance", &stdInterpreter}, + {0, 1, 0, 0, 0x00aa, "MeasuredColor", &stdInterpreter}, + {0, 1, 0, 0, 0x00ae, "ColorTemperature", &stdInterpreter}, + {0, 3, 0, 0, 0x00b0, "CanonFlags", &stdInterpreter}, + {0, 1, 0, 0, 0x00b1, "ModifiedInfo", &stdInterpreter}, + {0, 1, 0, 0, 0x00b2, "ToneCurveMatching", &stdInterpreter}, + {0, 1, 0, 0, 0x00b3, "WhiteBalanceMatching", &stdInterpreter}, + {0, 1, 0, 0, 0x00b4, "ColorSpace", &stdInterpreter}, + {1, 1, 0, 0, 0x00b6, "PreviewImageInfo", &stdInterpreter}, + {0, 1, 0, 0, 0x00d0, "VRDOffset", &stdInterpreter}, + {0, 1, 0, 0, 0x00e0, "SensorInfo", &stdInterpreter}, + {0, 1, 0, 0, 0x4001, "ColorBalance", &stdInterpreter}, + {0, 1, 0, 0, 0x4002, "UnknownBlock1", &stdInterpreter}, + {0, 1, 0, 0, 0x4003, "ColorInfo", &stdInterpreter}, + {1, 1, 0, 0, 0x4005, "UnknownBlock2", &stdInterpreter}, + {1, 1, 0, 0, 0x4008, "BlackLevel", &stdInterpreter}, + {1, 1, 0, canonMicroAdjustAttrib, 0x4013, "AFMicroAdj", &stdInterpreter}, + {-1, 0, 0, 0, 0, "", NULL}}; +} +#endif + diff --git a/rtexif/fujiattribs.cc b/rtexif/fujiattribs.cc new file mode 100644 index 000000000..93d2170f6 --- /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, 1, 0, 0, 0x0000, "Version", &stdInterpreter}, + {0, 1, 0, 0, 0x0010, "InternalSerialNumber", &stdInterpreter}, + {0, 1, 0, 0, 0x1000, "Quality", &stdInterpreter}, + {0, 1, 0, 0, 0x1001, "Sharpness", &faSharpnessInterpreter}, + {0, 1, 0, 0, 0x1002, "WhiteBalance", &faWhiteBalanceInterpreter}, + {0, 1, 0, 0, 0x1003, "Saturation", &faSaturationInterpreter}, + {0, 1, 0, 0, 0x1004, "Contrast", &faContrastInterpreter}, + {0, 1, 0, 0, 0x1005, "ColorTemperature", &stdInterpreter}, + {0, 1, 0, 0, 0x1006, "Contrast2", &faContrast2Interpreter}, + {0, 1, 0, 0, 0x100a, "WhiteBalanceFineTune", &stdInterpreter}, + {0, 1, 0, 0, 0x100b, "NoiseReduction", &faNoiseReductionInterpreter}, + {0, 1, 0, 0, 0x1010, "FujiFlashMode", &faFlashInterpreter}, + {0, 1, 0, 0, 0x1011, "FlashExposureComp", &stdInterpreter}, + {0, 1, 0, 0, 0x1020, "Macro", &faOnOffInterpreter}, + {0, 1, 0, 0, 0x1021, "FocusMode", &faFocusModeInterpreter}, + {0, 1, 0, 0, 0x1023, "FocusPixel", &stdInterpreter}, + {0, 1, 0, 0, 0x1030, "SlowSync", &faOnOffInterpreter}, + {0, 1, 0, 0, 0x1031, "PictureMode", &faPictureModeInterpreter}, + {0, 1, 0, 0, 0x1100, "AutoBracketing", &faOnOffInterpreter}, + {0, 1, 0, 0, 0x1101, "SequenceNumber", &stdInterpreter}, + {0, 1, 0, 0, 0x1210, "ColorMode", &faColorModeInterpreter}, + {0, 1, 0, 0, 0x1300, "BlurWarning", &faOnOffInterpreter}, + {0, 1, 0, 0, 0x1301, "FocusWarning", &faOnOffInterpreter}, + {0, 1, 0, 0, 0x1302, "ExposureWarning", &faOnOffInterpreter}, + {0, 1, 0, 0, 0x1400, "DynamicRange", &faDynamicRangeInterpreter}, + {0, 1, 0, 0, 0x1401, "FilmMode", &faFilmModeInterpreter}, + {0, 1, 0, 0, 0x1402, "DynamicRangeSetting", &faDRSettingInterpreter}, + {0, 1, 0, 0, 0x1403, "DevelopmentDynamicRange", &stdInterpreter}, + {0, 1, 0, 0, 0x1404, "MinFocalLength", &stdInterpreter}, + {0, 1, 0, 0, 0x1405, "MaxFocalLength", &stdInterpreter}, + {0, 1, 0, 0, 0x1406, "MaxApertureAtMinFocal", &stdInterpreter}, + {0, 1, 0, 0, 0x1407, "MaxApertureAtMaxFocal", &stdInterpreter}, + {0, 1, 0, 0, 0x140b, "AutoDynamicRange", &stdInterpreter}, + {0, 1, 0, 0, 0x4100, "FacesDetected", &stdInterpreter}, + {0, 1, 0, 0, 0x8000, "FileSource", &stdInterpreter}, + {0, 1, 0, 0, 0x8002, "OrderNumber", &stdInterpreter}, + {0, 1, 0, 0, 0x8003, "FrameNumber", &stdInterpreter}, + {-1, 0, 0, 0, 0, "", NULL}}; +} +#endif + diff --git a/rtexif/nikonattribs.cc b/rtexif/nikonattribs.cc new file mode 100644 index 000000000..bd1f0e176 --- /dev/null +++ b/rtexif/nikonattribs.cc @@ -0,0 +1,790 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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 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 << "Exposure Bracketing = " << (a&8 ? "Yes" : "No") << std::endl; + str << "Auto ISO = " << (a&16 ? "Yes" : "No") << std::endl; + str << "White-Balance Bracketing = " << (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 () { +/* 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 36 1C 2D 34 3C 00 06"] = "Tamron SP AF11-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 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 AF55-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"; + 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 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 APO 70-210mm f/2.8"; + 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 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 N"; + lenses["07 40 30 45 2D 35 03 02"] = "Tamron AF 19-35mm f/3.5-4.5"; + 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 F2.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 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["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 ED 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 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 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 AF 20-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["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:2 (172/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["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"; + 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-800 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 54 62 62 0C 0C 4D 02"] = "AF Nikkor 85mm f/1.4D IF"; + 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["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 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 APO 50-150mm f/2.8 EX 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 HSM"; + lenses["7A 48 5C 80 24 24 4B 06"] = "Sigma APO 70-200mm f/2.8 EX 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"; + 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["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["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 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["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 54 62 62 24 24 9F 02"] = "PC-E Micro Nikkor 85mm f/2.8D"; + 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 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["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["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["B6 48 37 56 24 24 1C 02"] = "Sigma 24-60mm f/2.8 EX DG"; + 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 APO 150-500mm f/5-6.3 DG OS 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 APO 70-300mm f/4-5.6 DG Macro HSM"; + lenses["E1 58 37 37 14 14 1C 02"] = "Sigma 24mm f/1.8 EX DG Aspherical Macro"; + lenses["E5 54 6A 6A 24 24 35 02"] = "Sigma 105mm f/2.8 EX 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 APO 70-200mm f/2.8 EX 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["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 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 55 64 64 24 24 84 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["FB 54 8E 8E 24 24 4B 02"] = "Sigma APO 300mm f/2.8 EX DG HSM"; + lenses["FD 47 50 76 24 24 4B 06"] = "Sigma APO 50-150mm f/2.8 EX 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 53 5C 80 24 24 84 06"] = "Tamron SP AF 70-200mm f/2.8 Di LD (IF) Macro (A001)"; + } + 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); + + std::string model = t->getParent()->getParent()->getParent()->getTag(0x0110)->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++); + } + + if (!d100) { + 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; + ld << "EffectiveMaxAperture = " << (int) buffer[14] << std::endl; + }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; + ld << "EffectiveMaxAperture = " << (int) buffer[15] << 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()) + ld << "Lens = " << r->second; + else + ld << "Lens = Unknown, ID=" << lid.str(); + + return ld.str(); + } + +}; +NALensDataInterpreter naLensDataInterpreter; + +const TagAttrib nikon2Attribs[] = { + {0, 1, 0, 0, 0x0002, "Unknown", &stdInterpreter}, + {0, 1, 0, 0, 0x0003, "Quality", &stdInterpreter}, + {0, 1, 0, 0, 0x0004, "ColorMode", &stdInterpreter}, + {0, 1, 0, 0, 0x0005, "ImageAdjustment", &stdInterpreter}, + {0, 1, 0, 0, 0x0006, "ISOSpeed", &naISOInterpreter}, + {0, 1, 0, 0, 0x0007, "WhiteBalance", &stdInterpreter}, + {0, 1, 0, 0, 0x0008, "Focus", &stdInterpreter}, + {0, 1, 0, 0, 0x0009, "Unknown", &stdInterpreter}, + {0, 1, 0, 0, 0x000a, "DigitalZoom", &stdInterpreter}, + {0, 1, 0, 0, 0x000b, "AuxiliaryLens", &stdInterpreter}, + {0, 1, 0, 0, 0x0f00, "Unknown", &stdInterpreter}, + {-1, 0, 0, 0, 0, "", NULL}}; + +const TagAttrib nikon3Attribs[] = { + {0, 1, 0, 0, 0x0001, "MakerNoteVersion", &stdInterpreter}, + {0, 1, 0, 0, 0x0002, "ISOSpeed", &naISOInterpreter}, + {0, 1, 0, 0, 0x0003, "ColorMode", &stdInterpreter}, + {0, 1, 0, 0, 0x0004, "Quality", &stdInterpreter}, + {0, 1, 0, 0, 0x0005, "WhiteBalance", &stdInterpreter}, + {0, 1, 0, 0, 0x0006, "Sharpness", &stdInterpreter}, + {0, 1, 0, 0, 0x0007, "FocusMode", &stdInterpreter}, + {0, 1, 0, 0, 0x0008, "FlashSetting", &stdInterpreter}, + {0, 1, 0, 0, 0x0009, "FlashType", &stdInterpreter}, + {0, 1, 0, 0, 0x000b, "WhiteBalanceFineTune", &stdInterpreter}, + {0, 3, 0, 0, 0x000c, "ColorBalance1", &stdInterpreter}, + {0, 1, 0, 0, 0x000d, "ProgramShift", &stdInterpreter}, + {0, 1, 0, 0, 0x000e, "ExposureDifference", &stdInterpreter}, + {0, 1, 0, 0, 0x000f, "ISOSelection", &naISOInterpreter}, + {0, 1, 0, 0, 0x0010, "DataDump", &stdInterpreter}, + {1, 1, 0, 0, 0x0011, "NikonPreview", &stdInterpreter}, + {0, 1, 0, 0, 0x0012, "FlashExposureComp", &stdInterpreter}, + {0, 1, 0, 0, 0x0013, "ISOSetting", &stdInterpreter}, + {0, 1, 0, 0, 0x0016, "ImageBoundary", &stdInterpreter}, + {0, 1, 0, 0, 0x0018, "FlashExposureBracketValue", &stdInterpreter}, + {0, 1, 0, 0, 0x0019, "ExposureBracketValue", &stdInterpreter}, + {0, 1, 0, 0, 0x001a, "ImageProcessing", &stdInterpreter}, + {0, 1, 0, 0, 0x001b, "CropHiSpeed", &stdInterpreter}, + {0, 1, 0, 0, 0x001d, "SerialNumber", &stdInterpreter}, + {0, 1, 0, 0, 0x001e, "ColorSpace", &stdInterpreter}, + {0, 1, 0, 0, 0x0020, "ImageAuthentication", &stdInterpreter}, + {0, 1, 0, 0, 0x0080, "ImageAdjustment", &stdInterpreter}, + {0, 1, 0, 0, 0x0081, "ToneComp", &stdInterpreter}, + {0, 1, 0, 0, 0x0082, "AuxiliaryLens", &stdInterpreter}, + {0, 1, 0, 0, 0x0083, "LensType", &naLensTypeInterpreter}, + {0, 1, 0, 0, 0x0084, "Lens", &stdInterpreter}, + {0, 1, 0, 0, 0x0085, "ManualFocusDistance", &stdInterpreter}, + {0, 1, 0, 0, 0x0086, "DigitalZoom", &stdInterpreter}, + {0, 1, 0, 0, 0x0087, "FlashMode", &naFlashModeInterpreter}, + {0, 1, 0, 0, 0x0088, "AFInfo", &naAFInfoInterpreter}, + {0, 1, 0, 0, 0x0089, "ShootingMode", &naShootingModeInterpreter}, + {0, 1, 0, 0, 0x008a, "AutoBracketRelease", &stdInterpreter}, + {0, 1, 0, 0, 0x008b, "LensFStops", &stdInterpreter}, + {0, 1, 0, 0, 0x008c, "NEFCurve1", &stdInterpreter}, + {0, 1, 0, 0, 0x008d, "ColorHue", &stdInterpreter}, + {0, 1, 0, 0, 0x008f, "SceneMode", &stdInterpreter}, + {0, 1, 0, 0, 0x0090, "LightSource", &stdInterpreter}, + {0, 1, 0, 0, 0x0091, "ShotInfo", &stdInterpreter}, + {0, 1, 0, 0, 0x0092, "HueAdjustment", &stdInterpreter}, + {0, 1, 0, 0, 0x0094, "Saturation", &stdInterpreter}, + {0, 1, 0, 0, 0x0095, "NoiseReduction", &stdInterpreter}, + {0, 1, 0, 0, 0x0096, "NEFCurve2", &stdInterpreter}, + {0, 3, 0, 0, 0x0097, "ColorBalance", &stdInterpreter}, + {0, 1, 0, 0, 0x0098, "LensData", &naLensDataInterpreter}, + {0, 1, 0, 0, 0x0099, "RawImageCenter", &stdInterpreter}, + {0, 1, 0, 0, 0x009a, "SensorPixelSize", &stdInterpreter}, + {0, 1, 0, 0, 0x00a0, "SerialNumber", &stdInterpreter}, + {0, 1, 0, 0, 0x00a2, "ImageDataSize", &stdInterpreter}, + {0, 1, 0, 0, 0x00a5, "ImageCount", &stdInterpreter}, + {0, 1, 0, 0, 0x00a6, "DeletedImageCount", &stdInterpreter}, + {0, 1, 0, 0, 0x00a7, "ShutterCount", &stdInterpreter}, + {0, 1, 0, 0, 0x00a9, "ImageOptimization", &stdInterpreter}, + {0, 1, 0, 0, 0x00aa, "Saturation", &stdInterpreter}, + {0, 1, 0, 0, 0x00ab, "VariProgram", &stdInterpreter}, + {0, 1, 0, 0, 0x00ac, "ImageStabilization", &stdInterpreter}, + {0, 1, 0, 0, 0x00ad, "AFResponse", &stdInterpreter}, + {0, 1, 0, 0, 0x00b0, "MultiExposure", &stdInterpreter}, + {0, 1, 0, 0, 0x00b1, "HighISONoiseReduction", &naHiISONRInterpreter}, + {0, 1, 0, 0, 0x0e00, "PrintIM", &stdInterpreter}, + {0, 0, 0, 0, 0x0e01, "NikonCaptureData", &stdInterpreter}, + {0, 0, 0, 0, 0x0e09, "NikonCaptureVersion", &stdInterpreter}, + {0, 0, 0, 0, 0x0e0e, "NikonCaptureOffsets", &stdInterpreter}, + {0, 0, 0, 0, 0x0e10, "NikonScanIFD", &stdInterpreter}, + {-1, 0, 0, 0, 0, "", NULL}}; + +} +#endif + diff --git a/rtexif/olympusattribs.cc b/rtexif/olympusattribs.cc new file mode 100644 index 000000000..9cc6206d0 --- /dev/null +++ b/rtexif/olympusattribs.cc @@ -0,0 +1,701 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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 () { + // 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 "; + 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 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 08 01"] = "Zuiko Digital 70-300mm f/4-5.6"; + lenses["00 15 00"] = "Zuiko Digital ED 7-14mm f/4"; + 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 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"; + lenses["01 02 00"] = "Sigma 55-200mm f/4-5.6 DC"; + lenses["01 03 00"] = "Sigma 18-125mm f/3.5-5.6 DC"; + lenses["01 04 00"] = "Sigma 18-125mm f/3.5-5.6"; + lenses["01 05 00"] = "Sigma 30mm f/1.4 DC"; + 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 DG"; + lenses["01 08 00"] = "Sigma 150mm f/2.8 DG HSM"; + 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 ASP APO RF"; + lenses["01 12 00"] = "Sigma 300-800mm f/5.6 EX DG APO"; + lenses["01 14 00"] = "Sigma 50-500mm f/4-6.3 EX DG APO HSM RF"; + lenses["01 15 00"] = "Sigma 10-20mm f/4-5.6 EX DC HSM"; + lenses["01 16 00"] = "Sigma 70-200mm f/2.8 EX DG Macro HSM II"; + 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 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 08 10"] = "Lumix G Fisheye 8mm f/3.5 "; + 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, 1, 0, 0, 0x0000, "FocusInfoVersion", &stdInterpreter}, + {0, 1, 0, 0, 0x0209, "AutoFocus", &olOnOffInterpreter}, + {0, 1, 0, 0, 0x0210, "SceneDetect", &stdInterpreter}, + {0, 1, 0, 0, 0x0211, "SceneArea", &stdInterpreter}, + {0, 1, 0, 0, 0x0212, "SceneDetectData", &stdInterpreter}, + {0, 1, 0, 0, 0x0300, "ZoomStepCount", &stdInterpreter}, + {0, 1, 0, 0, 0x0301, "FocusStepCount", &stdInterpreter}, + {0, 1, 0, 0, 0x0303, "FocusStepInfinity", &stdInterpreter}, + {0, 1, 0, 0, 0x0304, "FocusStepNear", &stdInterpreter}, + {0, 1, 0, 0, 0x0305, "FocusDistance", &stdInterpreter}, + {0, 1, 0, 0, 0x0308, "AFPoint", &stdInterpreter}, + {0, 1, 0, 0, 0x1201, "ExternalFlash", &olOnOffInterpreter}, + {0, 1, 0, 0, 0x1203, "ExternalFlashGuideNumber", &stdInterpreter}, + {0, 1, 0, 0, 0x1204, "ExternalFlashBounce", &stdInterpreter}, + {0, 1, 0, 0, 0x1205, "ExternalFlashZoom", &stdInterpreter}, + {0, 1, 0, 0, 0x1208, "InternalFlash", &olOnOffInterpreter}, + {0, 1, 0, 0, 0x1209, "ManualFlash", &olOnOffInterpreter}, + {0, 1, 0, 0, 0x1500, "SensorTemperature", &stdInterpreter}, + {0, 1, 0, 0, 0x1600, "ImageStabilization", &stdInterpreter}, + {-1, 0, 0, 0, 0, "", NULL}}; + +const TagAttrib olyImageProcessingAttribs[] = { + {0, 1, 0, 0, 0x0000, "ImageProcessingVersion", &stdInterpreter}, + {0, 1, 0, 0, 0x0100, "WB_RBLevels", &stdInterpreter}, + {0, 1, 0, 0, 0x0102, "WB_RBLevels3000K", &stdInterpreter}, + {0, 1, 0, 0, 0x0103, "WB_RBLevels3300K", &stdInterpreter}, + {0, 1, 0, 0, 0x0104, "WB_RBLevels3600K", &stdInterpreter}, + {0, 1, 0, 0, 0x0105, "WB_RBLevels3900K", &stdInterpreter}, + {0, 1, 0, 0, 0x0106, "WB_RBLevels4000K", &stdInterpreter}, + {0, 1, 0, 0, 0x0107, "WB_RBLevels4300K", &stdInterpreter}, + {0, 1, 0, 0, 0x0108, "WB_RBLevels4500K", &stdInterpreter}, + {0, 1, 0, 0, 0x0109, "WB_RBLevels4800K", &stdInterpreter}, + {0, 1, 0, 0, 0x010a, "WB_RBLevels5300K", &stdInterpreter}, + {0, 1, 0, 0, 0x010b, "WB_RBLevels6000K", &stdInterpreter}, + {0, 1, 0, 0, 0x010c, "WB_RBLevels6600K", &stdInterpreter}, + {0, 1, 0, 0, 0x010d, "WB_RBLevels7500K", &stdInterpreter}, + {0, 1, 0, 0, 0x010e, "WB_RBLevelsCWB1", &stdInterpreter}, + {0, 1, 0, 0, 0x010f, "WB_RBLevelsCWB2", &stdInterpreter}, + {0, 1, 0, 0, 0x0110, "WB_RBLevelsCWB3", &stdInterpreter}, + {0, 1, 0, 0, 0x0111, "WB_RBLevelsCWB4", &stdInterpreter}, + {0, 1, 0, 0, 0x0113, "WB_GLevel3000K", &stdInterpreter}, + {0, 1, 0, 0, 0x0114, "WB_GLevel3300K", &stdInterpreter}, + {0, 1, 0, 0, 0x0115, "WB_GLevel3600K", &stdInterpreter}, + {0, 1, 0, 0, 0x0116, "WB_GLevel3900K", &stdInterpreter}, + {0, 1, 0, 0, 0x0117, "WB_GLevel4000K", &stdInterpreter}, + {0, 1, 0, 0, 0x0118, "WB_GLevel4300K", &stdInterpreter}, + {0, 1, 0, 0, 0x0119, "WB_GLevel4500K", &stdInterpreter}, + {0, 1, 0, 0, 0x011a, "WB_GLevel4800K", &stdInterpreter}, + {0, 1, 0, 0, 0x011b, "WB_GLevel5300K", &stdInterpreter}, + {0, 1, 0, 0, 0x011c, "WB_GLevel6000K", &stdInterpreter}, + {0, 1, 0, 0, 0x011d, "WB_GLevel6600K", &stdInterpreter}, + {0, 1, 0, 0, 0x011e, "WB_GLevel7500K", &stdInterpreter}, + {0, 1, 0, 0, 0x011f, "WB_GLevel", &stdInterpreter}, + {0, 1, 0, 0, 0x0200, "ColorMatrix", &stdInterpreter}, + {0, 1, 0, 0, 0x0300, "Enhancer", &stdInterpreter}, + {0, 1, 0, 0, 0x0301, "EnhancerValues", &stdInterpreter}, + {0, 1, 0, 0, 0x0310, "CoringFilter", &stdInterpreter}, + {0, 1, 0, 0, 0x0311, "CoringValues", &stdInterpreter}, + {0, 1, 0, 0, 0x0600, "BlackLevel2", &stdInterpreter}, + {0, 1, 0, 0, 0x0610, "GainBase", &stdInterpreter}, + {0, 1, 0, 0, 0x0611, "ValidBits", &stdInterpreter}, + {0, 1, 0, 0, 0x0612, "CropLeft", &stdInterpreter}, + {0, 1, 0, 0, 0x0613, "CropTop", &stdInterpreter}, + {0, 1, 0, 0, 0x0614, "CropWidth", &stdInterpreter}, + {0, 1, 0, 0, 0x0615, "CropHeight", &stdInterpreter}, + {0, 1, 0, 0, 0x1010, "NoiseReduction2", &stdInterpreter}, + {0, 1, 0, 0, 0x1011, "DistortionCorrection2", &olOnOffInterpreter}, + {0, 1, 0, 0, 0x1012, "ShadingCompensation2", &olOnOffInterpreter}, + {1, 1, 0, 0, 0x1103, "UnknownBlock", &stdInterpreter}, + {0, 1, 0, 0, 0x1200, "FaceDetect", &olOnOffInterpreter}, + {0, 1, 0, 0, 0x1201, "FaceDetectArea", &stdInterpreter}, + {-1, 0, 0, 0, 0, "", NULL}}; + +const TagAttrib olyRawDevelopmentAttribs[] = { + {0, 1, 0, 0, 0x0000, "RawDevVersion", &stdInterpreter}, + {0, 1, 0, 0, 0x0100, "RawDevExposureBiasValue", &stdInterpreter}, + {0, 1, 0, 0, 0x0101, "RawDevWhiteBalanceValue", &stdInterpreter}, + {0, 1, 0, 0, 0x0102, "RawDevWBFineAdjustment", &stdInterpreter}, + {0, 1, 0, 0, 0x0103, "RawDevGrayPoint", &stdInterpreter}, + {0, 1, 0, 0, 0x0104, "RawDevSaturationEmphasis", &stdInterpreter}, + {0, 1, 0, 0, 0x0105, "RawDevMemoryColorEmphasis", &stdInterpreter}, + {0, 1, 0, 0, 0x0106, "RawDevContrastValue", &stdInterpreter}, + {0, 1, 0, 0, 0x0107, "RawDevSharpnessValue", &stdInterpreter}, + {0, 1, 0, 0, 0x0108, "RawDevColorSpace", &olColorSpaceInterpreter}, + {0, 1, 0, 0, 0x0109, "RawDevEngine", &olDevEngineInterpreter}, + {0, 1, 0, 0, 0x010a, "RawDevNoiseReduction", &olNoiseReductionInterpreter}, + {0, 1, 0, 0, 0x010b, "RawDevEditStatus", &stdInterpreter}, + {0, 1, 0, 0, 0x010c, "RawDevSettings", &stdInterpreter}, + {-1, 0, 0, 0, 0, "", NULL}}; + +const TagAttrib olyRawDevelopment2Attribs[] = { + {0, 1, 0, 0, 0x0000, "RawDevVersion", &stdInterpreter}, + {0, 1, 0, 0, 0x0100, "RawDevExposureBiasValue", &stdInterpreter}, + {0, 1, 0, 0, 0x0101, "RawDevWhiteBalance", &stdInterpreter}, + {0, 1, 0, 0, 0x0102, "RawDevWhiteBalanceValue", &stdInterpreter}, + {0, 1, 0, 0, 0x0103, "RawDevWBFineAdjustment", &stdInterpreter}, + {0, 1, 0, 0, 0x0104, "RawDevGrayPoint", &stdInterpreter}, + {0, 1, 0, 0, 0x0105, "RawDevContrastValue", &stdInterpreter}, + {0, 1, 0, 0, 0x0106, "RawDevSharpnessValue", &stdInterpreter}, + {0, 1, 0, 0, 0x0107, "RawDevSaturationEmphasis", &stdInterpreter}, + {0, 1, 0, 0, 0x0108, "RawDevMemoryColorEmphasis", &stdInterpreter}, + {0, 1, 0, 0, 0x0109, "RawDevColorSpace", &olColorSpaceInterpreter}, + {0, 1, 0, 0, 0x010a, "RawDevNoiseReduction", &olNoiseReductionInterpreter}, + {0, 1, 0, 0, 0x010b, "RawDevEngine", &olDevEngineInterpreter}, + {0, 1, 0, 0, 0x010c, "RawDevPictureMode", &olPictureModeInterpreter}, + {0, 1, 0, 0, 0x010d, "RawDevPMSaturation", &stdInterpreter}, + {0, 1, 0, 0, 0x010e, "RawDevPMContrast", &stdInterpreter}, + {0, 1, 0, 0, 0x010f, "RawDevPMSharpness", &stdInterpreter}, + {0, 1, 0, 0, 0x0110, "RawDevPM_BWFilter", &olPictureModeBWFilterInterpreter}, + {0, 1, 0, 0, 0x0111, "RawDevPMPictureTone", &olPictureModeToneInterpreter}, + {0, 1, 0, 0, 0x0112, "RawDevGradation", &stdInterpreter}, + {0, 1, 0, 0, 0x0113, "RawDevSaturation3", &stdInterpreter}, + {0, 1, 0, 0, 0x0119, "RawDevAutoGradation", &olOnOffInterpreter}, + {0, 1, 0, 0, 0x0120, "RawDevPMNoiseFilter", &stdInterpreter}, + {-1, 0, 0, 0, 0, "", NULL}}; + +const TagAttrib olyCameraSettingsAttribs[] = { + {0, 1, 0, 0, 0x0000, "CameraSettingsVersion", &stdInterpreter}, + {1, 1, 0, 0, 0x0100, "PreviewImageValid", &olYesNoInterpreter}, + {1, 1, 0, 0, 0x0101, "PreviewImageStart", &stdInterpreter}, + {1, 1, 0, 0, 0x0102, "PreviewImageLength", &stdInterpreter}, + {0, 1, 0, 0, 0x0200, "ExposureMode", &olExposureModeInterpreter}, + {0, 1, 0, 0, 0x0201, "AELock", &olOnOffInterpreter}, + {0, 1, 0, 0, 0x0202, "MeteringMode", &olMeteringModeInterpreter}, + {0, 1, 0, 0, 0x0300, "MacroMode", &olOnOffInterpreter}, + {0, 1, 0, 0, 0x0301, "FocusMode", &olFocusModeInterpreter}, + {0, 1, 0, 0, 0x0302, "FocusProcess", &stdInterpreter}, + {0, 1, 0, 0, 0x0303, "AFSearch", &stdInterpreter}, + {0, 1, 0, 0, 0x0304, "AFAreas", &stdInterpreter}, + {0, 1, 0, 0, 0x0400, "FlashMode", &stdInterpreter}, + {0, 1, 0, 0, 0x0401, "FlashExposureComp", &stdInterpreter}, + {0, 1, 0, 0, 0x0500, "WhiteBalance2", &olWhitebalance2Interpreter}, + {0, 1, 0, 0, 0x0501, "WhiteBalanceTemperature", &stdInterpreter}, + {0, 1, 0, 0, 0x0502, "WhiteBalanceBracket", &stdInterpreter}, + {0, 1, 0, 0, 0x0503, "CustomSaturation", &stdInterpreter}, + {0, 1, 0, 0, 0x0504, "ModifiedSaturation", &stdInterpreter}, + {0, 1, 0, 0, 0x0505, "ContrastSetting", &stdInterpreter}, + {0, 1, 0, 0, 0x0506, "SharpnessSetting", &stdInterpreter}, + {0, 1, 0, 0, 0x0507, "ColorSpace", &olColorSpaceInterpreter}, + {0, 1, 0, 0, 0x0509, "SceneMode", &olSceneModeInterpreter}, + {0, 1, 0, 0, 0x050a, "NoiseReduction", &olNoiseReductionInterpreter}, + {0, 1, 0, 0, 0x050b, "DistortionCorrection", &olOnOffInterpreter}, + {0, 1, 0, 0, 0x050c, "ShadingCompensation", &olOnOffInterpreter}, + {0, 1, 0, 0, 0x050d, "CompressionFactor", &stdInterpreter}, + {0, 1, 0, 0, 0x050f, "Gradation", &stdInterpreter}, + {0, 1, 0, 0, 0x0520, "PictureMode", &olPictureModeInterpreter}, + {0, 1, 0, 0, 0x0521, "PictureModeSaturation", &stdInterpreter}, + {0, 1, 0, 0, 0x0522, "PictureModeHue", &stdInterpreter}, + {0, 1, 0, 0, 0x0523, "PictureModeContrast", &stdInterpreter}, + {0, 1, 0, 0, 0x0524, "PictureModeSharpness", &stdInterpreter}, + {0, 1, 0, 0, 0x0525, "PictureModeBWFilter", &olPictureModeBWFilterInterpreter}, + {0, 1, 0, 0, 0x0526, "PictureModeTone", &olPictureModeToneInterpreter}, + {0, 1, 0, 0, 0x0527, "NoiseFilter", &olNoiseFilterInterpreter}, + {0, 1, 0, 0, 0x0600, "DriveMode", &stdInterpreter}, + {0, 1, 0, 0, 0x0601, "PanoramaMode", &stdInterpreter}, + {0, 1, 0, 0, 0x0603, "ImageQuality2", &olImageQuality2Interpreter}, + {0, 1, 0, 0, 0x0900, "ManometerPressure", &stdInterpreter}, + {0, 1, 0, 0, 0x0901, "ManometerReading", &stdInterpreter}, + {0, 1, 0, 0, 0x0902, "ExtendedWBDetect", &olOnOffInterpreter}, + {-1, 0, 0, 0, 0, "", NULL}}; + +const TagAttrib olyEquipmentAttribs[] = { + {0, 1, 0, 0, 0x0000, "EquipmentVersion", &stdInterpreter}, + {0, 1, 0, 0, 0x0100, "CameraType2", &stdInterpreter}, + {0, 1, 0, 0, 0x0101, "SerialNumber", &stdInterpreter}, + {0, 1, 0, 0, 0x0102, "InternalSerialNumber", &stdInterpreter}, + {0, 1, 0, 0, 0x0103, "FocalPlaneDiagonal", &stdInterpreter}, + {0, 1, 0, 0, 0x0104, "BodyFirmwareVersion", &stdInterpreter}, + {0, 1, 0, 0, 0x0201, "LensType", &olLensTypeInterpreter}, + {0, 1, 0, 0, 0x0202, "LensSerialNumber", &stdInterpreter}, + {0, 1, 0, 0, 0x0204, "LensFirmwareVersion", &stdInterpreter}, + {0, 1, 0, 0, 0x0205, "MaxApertureAtMinFocal", &olApertureInterpreter}, + {0, 1, 0, 0, 0x0206, "MaxApertureAtMaxFocal", &olApertureInterpreter}, + {0, 1, 0, 0, 0x0207, "MinFocalLength", &stdInterpreter}, + {0, 1, 0, 0, 0x0208, "MaxFocalLength", &stdInterpreter}, + {0, 1, 0, 0, 0x020a, "MaxApertureAtCurrentFocal", &olApertureInterpreter}, + {0, 1, 0, 0, 0x020b, "LensProperties", &stdInterpreter}, + {0, 1, 0, 0, 0x0301, "Extender", &stdInterpreter}, + {0, 1, 0, 0, 0x0302, "ExtenderSerialNumber", &stdInterpreter}, + {0, 1, 0, 0, 0x0303, "ExtenderModel", &stdInterpreter}, + {0, 1, 0, 0, 0x0304, "ExtenderFirmwareVersion", &stdInterpreter}, + {0, 1, 0, 0, 0x1000, "FlashType", &olFlashTypeInterpreter}, + {0, 1, 0, 0, 0x1001, "FlashModel", &olFlashModelInterpreter}, + {0, 1, 0, 0, 0x1002, "FlashFirmwareVersion", &stdInterpreter}, + {0, 1, 0, 0, 0x1003, "FlashSerialNumber", &stdInterpreter}, + {-1, 0, 0, 0, 0, "", NULL}}; + +const TagAttrib olympusAttribs[] = { + {0, 1, 0, 0, 0x0104, "BodyFirmwareVersion", &stdInterpreter}, + {0, 1, 0, 0, 0x0200, "SpecialMode", &stdInterpreter}, + {0, 1, 0, 0, 0x0201, "Quality", &stdInterpreter}, + {0, 1, 0, 0, 0x0202, "Macro", &olOnOffInterpreter}, + {0, 1, 0, 0, 0x0203, "BWMode", &olOnOffInterpreter}, + {0, 1, 0, 0, 0x0204, "DigitalZoom", &stdInterpreter}, + {0, 1, 0, 0, 0x0205, "FocalPlaneDiagonal", &stdInterpreter}, + {0, 1, 0, 0, 0x0206, "LensDistortionParams", &stdInterpreter}, + {0, 1, 0, 0, 0x0207, "CameraType", &stdInterpreter}, + {1, 1, 0, 0, 0x0208, "TextInfo", &stdInterpreter}, + {0, 1, 0, 0, 0x0209, "CameraID", &stdInterpreter}, + {0, 1, 0, 0, 0x020b, "EpsonImageWidth", &stdInterpreter}, + {0, 1, 0, 0, 0x020c, "EpsonImageHeight", &stdInterpreter}, + {0, 1, 0, 0, 0x020d, "EpsonSoftware", &stdInterpreter}, + {0, 2, 0, 0, 0x0280, "PreviewImage", &stdInterpreter}, + {0, 1, 0, 0, 0x0300, "PreCaptureFrames", &stdInterpreter}, + {0, 1, 0, 0, 0x0301, "WhiteBoard", &stdInterpreter}, + {0, 1, 0, 0, 0x0302, "OneTouchWB", &olOnOffInterpreter}, + {0, 1, 0, 0, 0x0303, "WhiteBalanceBracket", &stdInterpreter}, + {0, 1, 0, 0, 0x0304, "WhiteBalanceBias", &stdInterpreter}, + {0, 1, 0, 0, 0x0403, "SceneMode", &stdInterpreter}, + {0, 1, 0, 0, 0x0404, "SerialNumber", &stdInterpreter}, + {0, 1, 0, 0, 0x0405, "Firmware", &stdInterpreter}, + {1, 1, 0, 0, 0x0e00, "PrintIM", &stdInterpreter}, + {0, 1, 0, 0, 0x0f00, "DataDump", &stdInterpreter}, + {0, 1, 0, 0, 0x0f01, "DataDump2", &stdInterpreter}, + {0, 1, 0, 0, 0x1000, "ShutterSpeedValue", &stdInterpreter}, + {0, 1, 0, 0, 0x1001, "ISOValue", &stdInterpreter}, + {0, 1, 0, 0, 0x1002, "ApertureValue", &stdInterpreter}, + {0, 1, 0, 0, 0x1003, "BrightnessValue", &stdInterpreter}, + {0, 1, 0, 0, 0x1004, "FlashMode", &stdInterpreter}, + {0, 1, 0, 0, 0x1005, "FlashDevice", &stdInterpreter}, + {0, 1, 0, 0, 0x1006, "ExposureCompensation", &stdInterpreter}, + {0, 1, 0, 0, 0x1007, "SensorTemperature", &stdInterpreter}, + {0, 1, 0, 0, 0x1008, "LensTemperature", &stdInterpreter}, + {0, 1, 0, 0, 0x1009, "LightCondition", &stdInterpreter}, + {0, 1, 0, 0, 0x100a, "FocusRange", &stdInterpreter}, + {0, 1, 0, 0, 0x100b, "FocusMode", &stdInterpreter}, + {0, 1, 0, 0, 0x100c, "ManualFocusDistance", &stdInterpreter}, + {0, 1, 0, 0, 0x100d, "ZoomStepCount", &stdInterpreter}, + {0, 1, 0, 0, 0x100e, "FocusStepCount", &stdInterpreter}, + {0, 1, 0, 0, 0x100f, "Sharpness", &stdInterpreter}, + {0, 1, 0, 0, 0x1010, "FlashChargeLevel", &stdInterpreter}, + {0, 1, 0, 0, 0x1011, "ColorMatrix", &stdInterpreter}, + {0, 1, 0, 0, 0x1012, "BlackLevel", &stdInterpreter}, + {0, 1, 0, 0, 0x1013, "ColorTemperatureBG", &stdInterpreter}, + {0, 1, 0, 0, 0x1014, "ColorTemperatureRG", &stdInterpreter}, + {0, 1, 0, 0, 0x1015, "WBMode", &stdInterpreter}, + {0, 1, 0, 0, 0x1017, "RedBalance", &stdInterpreter}, + {0, 1, 0, 0, 0x1018, "BlueBalance", &stdInterpreter}, + {0, 1, 0, 0, 0x1019, "ColorMatrixNumber", &stdInterpreter}, + {0, 1, 0, 0, 0x101a, "SerialNumber", &stdInterpreter}, + {0, 1, 0, 0, 0x101b, "ExternalFlashAE1_0", &stdInterpreter}, + {0, 1, 0, 0, 0x101c, "ExternalFlashAE2_0", &stdInterpreter}, + {0, 1, 0, 0, 0x101d, "InternalFlashAE1_0", &stdInterpreter}, + {0, 1, 0, 0, 0x101e, "InternalFlashAE2_0", &stdInterpreter}, + {0, 1, 0, 0, 0x101f, "ExternalFlashAE1", &stdInterpreter}, + {0, 1, 0, 0, 0x1020, "ExternalFlashAE2", &stdInterpreter}, + {0, 1, 0, 0, 0x1021, "InternalFlashAE1", &stdInterpreter}, + {0, 1, 0, 0, 0x1022, "InternalFlashAE2", &stdInterpreter}, + {0, 1, 0, 0, 0x1023, "FlashExposureComp", &stdInterpreter}, + {0, 1, 0, 0, 0x1024, "InternalFlashTable", &stdInterpreter}, + {0, 1, 0, 0, 0x1025, "ExternalFlashGValue", &stdInterpreter}, + {0, 1, 0, 0, 0x1026, "ExternalFlashBounce", &olYesNoInterpreter}, + {0, 1, 0, 0, 0x1027, "ExternalFlashZoom", &stdInterpreter}, + {0, 1, 0, 0, 0x1028, "ExternalFlashMode", &stdInterpreter}, + {0, 1, 0, 0, 0x1029, "Contrast", &stdInterpreter}, + {0, 1, 0, 0, 0x102a, "SharpnessFactor", &stdInterpreter}, + {0, 1, 0, 0, 0x102b, "ColorControl", &stdInterpreter}, + {0, 1, 0, 0, 0x102c, "ValidBits", &stdInterpreter}, + {0, 1, 0, 0, 0x102d, "CoringFilter", &stdInterpreter}, + {0, 1, 0, 0, 0x102e, "OlympusImageWidth", &stdInterpreter}, + {0, 1, 0, 0, 0x102f, "OlympusImageHeight", &stdInterpreter}, + {0, 1, 0, 0, 0x1030, "SceneDetect", &stdInterpreter}, + {0, 1, 0, 0, 0x1031, "SceneArea", &stdInterpreter}, + {0, 1, 0, 0, 0x1033, "SceneDetectData", &stdInterpreter}, + {0, 1, 0, 0, 0x1034, "CompressionRatio", &stdInterpreter}, + {1, 1, 0, 0, 0x1035, "PreviewImageValid", &olYesNoInterpreter}, + {1, 1, 0, 0, 0x1036, "PreviewImageStart", &stdInterpreter}, + {1, 1, 0, 0, 0x1037, "PreviewImageLength", &stdInterpreter}, + {0, 1, 0, 0, 0x1038, "AFResult", &stdInterpreter}, + {0, 1, 0, 0, 0x1039, "CCDScanMode", &stdInterpreter}, + {0, 1, 0, 0, 0x103a, "NoiseReduction", &olOnOffInterpreter}, + {0, 1, 0, 0, 0x103b, "InfinityLensStep", &stdInterpreter}, + {0, 1, 0, 0, 0x103c, "NearLensStep", &stdInterpreter}, + {0, 1, 0, 0, 0x103d, "LightValueCenter", &stdInterpreter}, + {0, 1, 0, 0, 0x103e, "LightValuePeriphery", &stdInterpreter}, + {0, 1, 0, 0, 0x103f, "FieldCount", &stdInterpreter}, + {0, 1, 0, olyEquipmentAttribs, 0x2010, "Equipment", &stdInterpreter}, + {0, 1, 0, olyCameraSettingsAttribs, 0x2020, "CameraSettings", &stdInterpreter}, + {0, 1, 0, olyRawDevelopmentAttribs, 0x2030, "RawDevelopment", &stdInterpreter}, + {0, 1, 0, olyRawDevelopment2Attribs, 0x2031, "RawDev2", &stdInterpreter}, + {0, 1, 0, olyImageProcessingAttribs, 0x2040, "ImageProcessing", &stdInterpreter}, + {0, 1, 0, olyFocusInfoAttribs, 0x2050, "FocusInfo", &stdInterpreter}, + {1, 1, 0, 0, 0x2100, "Olympus2100", &stdInterpreter}, + {1, 1, 0, 0, 0x2300, "Olympus2300", &stdInterpreter}, + {1, 1, 0, 0, 0x2400, "Olympus2400", &stdInterpreter}, + {1, 1, 0, 0, 0x2500, "Olympus2500", &stdInterpreter}, + {1, 1, 0, 0, 0x2600, "Olympus2600", &stdInterpreter}, + {1, 1, 0, 0, 0x2700, "Olympus2700", &stdInterpreter}, + {1, 1, 0, 0, 0x2800, "Olympus2800", &stdInterpreter}, + {1, 1, 0, 0, 0x2900, "Olympus2900", &stdInterpreter}, + {0, 1, 0, 0, 0x3000, "RawInfo", &stdInterpreter}, + {-1, 0, 0, 0, 0, "", NULL}}; +} +#endif + diff --git a/rtexif/pentaxattribs.cc b/rtexif/pentaxattribs.cc new file mode 100644 index 000000000..1abb90c9a --- /dev/null +++ b/rtexif/pentaxattribs.cc @@ -0,0 +1,1207 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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 +#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[50] = "50"; + choices[100] = "100"; + choices[200] = "200"; + 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[400] = "400"; + choices[800] = "800"; + choices[1600] = "1600"; + choices[3200] = "3200"; + } +}; +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 () { + choices.insert(p_t( 0,"M-42 or No Lens")); + choices.insert(p_t(256*1, "K,M Lens")); + choices.insert(p_t(256*2, "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-5.6 DL IF")); + 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+ 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 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+ 50, "smc PENTAX-FA 28-70 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 (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 AF 70-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+ 75, "Tamron SP AF 70-200 f/2.8 Di LD [IF] Macro (A001)")); + 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 D-XENON 12-24mm f/4 ED AL [IF]")); + 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, "Schneider D-XENON 50-200mm")); + choices.insert(p_t(256*4+ 246, "Schneider D-XENON 18-55mm")); + 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+ 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+ 222, "smc PENTAX-DA 18-55mm f/3.5-5.6 AL II")); + choices.insert(p_t(256*7+ 223, "Samsung 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 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+ 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+ 14, "Sigma 17-70mm f/2.8-4.0 DC Macro OS HSM")); + 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 APO 150-500mm f/5-6.3 DG OS HSM")); + choices.insert(p_t(256*11+ 4, "smc PENTAX-FA 645 45-85mm f/4.5")); + choices.insert(p_t(256*11+ 8, "smc PENTAX-FA 645 80-160mm f/4.5")); + choices.insert(p_t(256*11+ 11, "smc PENTAX-FA 645 35mm f/3.5 AL [IF]")); + 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")); + } + virtual std::string toString (Tag* t) { + 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"); + if( t1) + focalLength = t1->toDouble(); // Focal Length + t1 = root->findTag("MaxAperture"); + if( t1){ + int a=t1->toInt(0,BYTE)&0x7F; + maxApertureAtFocal = pow(2.0, (a-1)/32.0) ; // MaxApertureValue at focal Length + } + } + return guess( lensID, focalLength, maxApertureAtFocal); + } +}; +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 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"; + } +}; +PAMaxApertureInterpreter paMaxApertureInterpreter; + +class PANominalMinMaxApertureInterpreter: public Interpreter { +public: + PANominalMinMaxApertureInterpreter(){} + virtual std::string toString (Tag* t){ + char buffer[1024]; + int a = t->toInt(0,BYTE); + int mina = a & 0x0F; + int maxa = (a & 0xF0)>>4; + sprintf (buffer, "%.1f - %.0f", pow(2.0, maxa/4.0), pow(2.0, (mina+10)/4.0)); + return buffer; + + } +}; +PANominalMinMaxApertureInterpreter paNominalMinMaxApertureInterpreter; + +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, 1, 0, 0, 0x0000, "PentaxVersion", &stdInterpreter}, + {0, 1, 0, 0, 0x0001, "PentaxModelType", &stdInterpreter}, + {0, 2, 0, 0, 0x0002, "PreviewImageSize", &stdInterpreter}, + {0, 2, 0, 0, 0x0003, "PreviewImageLength", &stdInterpreter}, + {0, 2, 0, 0, 0x0004, "PreviewImageStart", &stdInterpreter}, + {0, 1, 0, 0, 0x0005, "PentaxModelID", &stdInterpreter}, + {0, 1, 0, 0, 0x0006, "Date", &stdInterpreter}, + {0, 1, 0, 0, 0x0007, "Time", &stdInterpreter}, + {0, 1, 0, 0, 0x0008, "Quality", &paQualityInterpreter}, + {0, 1, 0, 0, 0x0009, "PentaxImageSize", &stdInterpreter}, + {0, 1, 0, 0, 0x000b, "PictureMode", &paPictureModeInterpreter}, + {0, 1, 0, 0, 0x000c, "FlashMode", &paFlashModeInterpreter}, + {0, 1, 0, 0, 0x000d, "FocusMode", &paFocusModeInterpreter}, + {0, 1, 0, 0, 0x000e, "AFPointSelected", &paAFPointInterpreter}, + {0, 1, 0, 0, 0x000f, "AFPointsInFocus", &paAFFocusInterpreter}, + {0, 1, 0, 0, 0x0010, "FocusPosition", &stdInterpreter}, + {0, 1, 0, 0, 0x0012, "ExposureTime", &stdInterpreter}, + {0, 1, 0, 0, 0x0013, "FNumber", &paFNumberInterpreter}, + {0, 1, 0, 0, 0x0014, "ISO", &paISOInterpreter}, + {0, 1, 0, 0, 0x0015, "LightReading", &stdInterpreter}, + {0, 1, 0, 0, 0x0016, "ExposureCompensation", &stdInterpreter}, + {0, 1, 0, 0, 0x0017, "MeteringMode", &paMeteringModeInterpreter}, + {0, 1, 0, 0, 0x0018, "AutoBracketing", &stdInterpreter}, + {0, 1, 0, 0, 0x0019, "WhiteBalance", &paWhiteBalanceInterpreter}, + {0, 1, 0, 0, 0x001a, "WhiteBalanceMode", &paWhiteBalanceModeInterpreter}, + {0, 1, 0, 0, 0x001b, "BlueBalance", &stdInterpreter}, + {0, 1, 0, 0, 0x001c, "RedBalance", &stdInterpreter}, + {0, 1, 0, 0, 0x001d, "FocalLength", &stdInterpreter}, + {0, 1, 0, 0, 0x001e, "DigitalZoom", &stdInterpreter}, + {0, 1, 0, 0, 0x001f, "Saturation", &paSaturationInterpreter}, + {0, 1, 0, 0, 0x0020, "Contrast", &paContrastInterpreter}, + {0, 1, 0, 0, 0x0021, "Sharpness", &paSharpnessInterpreter}, + {0, 1, 0, 0, 0x0022, "WorldTimeLocation", &stdInterpreter}, + {0, 1, 0, 0, 0x0023, "HometownCity", &stdInterpreter}, + {0, 3, 0, 0, 0x0024, "DestinationCity", &stdInterpreter}, + {0, 3, 0, 0, 0x0025, "HometownDST", &stdInterpreter}, + {0, 1, 0, 0, 0x0026, "DestinationDST", &stdInterpreter}, + {0, 1, 0, 0, 0x0027, "DSPFirmwareVersion", &stdInterpreter}, + {0, 1, 0, 0, 0x0028, "CPUFirmwareVersion", &stdInterpreter}, + {0, 1, 0, 0, 0x0029, "FrameNumber", &stdInterpreter}, + {0, 1, 0, 0, 0x002d, "EffectiveLV", &stdInterpreter}, + {0, 1, 0, 0, 0x0032, "ImageProcessing", &stdInterpreter}, + {0, 1, 0, 0, 0x0033, "PictureMode", &paPictureModeInterpreter2}, + {0, 1, 0, 0, 0x0034, "DriveMode", &paDriveModeInterpreter}, + {0, 1, 0, 0, 0x0037, "ColorSpace", &paColorSpaceInterpreter}, + {0, 1, 0, 0, 0x0038, "ImageAreaOffset", &stdInterpreter}, + {0, 1, 0, 0, 0x0039, "RawImageSize", &stdInterpreter}, + {0, 1, 0, 0, 0x003c, "AFPointsInFocus", &stdInterpreter}, + {0, 1, 0, 0, 0x003e, "PreviewImageBorders", &stdInterpreter}, + {0, 1, 0, 0, 0x003f, "LensType", &paLensTypeInterpreter}, + {0, 1, 0, 0, 0x0040, "SensitivityAdjust", &stdInterpreter}, + {0, 1, 0, 0, 0x0041, "ImageProcessingCount", &stdInterpreter}, + {0, 1, 0, 0, 0x0047, "CameraTemperature", &stdInterpreter}, + {0, 1, 0, 0, 0x0048, "AELock", &paOnOffInterpreter}, + {0, 1, 0, 0, 0x0049, "NoiseReduction", &paOnOffInterpreter}, + {0, 1, 0, 0, 0x004d, "FlashExposureComp", &stdInterpreter}, + {0, 1, 0, 0, 0x004f, "ImageTone", &stdInterpreter}, + {0, 1, 0, 0, 0x0050, "ColorTemperature", &stdInterpreter}, + {0, 1, 0, pentaxSRInfoAttribs, 0x005c, "ShakeReductionInfo", &stdInterpreter}, + {0, 1, 0, 0, 0x005d, "ShutterCount", &stdInterpreter}, + {0, 1, 0, 0, 0x0069, "DynamicRangeExpansion", &paOnOffInterpreter}, + {0, 1, 0, 0, 0x0071, "HighISONoiseReduction", &paHighISONoiseInterpreter}, + {0, 1, 0, 0, 0x0072, "AFAdjustment", &stdInterpreter}, + {0, 1, 0, 0, 0x0200, "BlackPoint", &stdInterpreter}, + {0, 1, 0, 0, 0x0201, "WhitePoint", &stdInterpreter}, + {0, 1, 0, 0, 0x0203, "ColorMatrixA", &stdInterpreter}, + {0, 1, 0, 0, 0x0204, "ColorMatrixB", &stdInterpreter}, + {0, 1, 0, pentaxCameraSettingsAttribs, 0x0205, "CameraSettings", &stdInterpreter}, + {0, 1, 0, pentaxAEInfoAttribs, 0x0206, "AEInfo", &stdInterpreter}, + {0, 1, 0, pentaxLensDataAttribs, 0x0207, "LensInfo", &stdInterpreter}, + {0, 1, 0, pentaxFlashInfoAttribs, 0x0208, "FlashInfo", &stdInterpreter}, + {0, 1, 0, 0, 0x0209, "AEMeteringSegments", &stdInterpreter}, + {0, 1, 0, 0, 0x020a, "FlashADump", &stdInterpreter}, + {0, 1, 0, 0, 0x020b, "FlashBDump", &stdInterpreter}, + {0, 1, 0, 0, 0x020d, "WB_RGGBLevelsDaylight", &stdInterpreter}, + {0, 1, 0, 0, 0x020e, "WB_RGGBLevelsShade", &stdInterpreter}, + {0, 1, 0, 0, 0x020f, "WB_RGGBLevelsCloudy", &stdInterpreter}, + {0, 1, 0, 0, 0x0210, "WB_RGGBLevelsTungsten", &stdInterpreter}, + {0, 1, 0, 0, 0x0211, "WB_RGGBLevelsFluorescentD", &stdInterpreter}, + {0, 1, 0, 0, 0x0212, "WB_RGGBLevelsFluorescentN", &stdInterpreter}, + {0, 1, 0, 0, 0x0213, "WB_RGGBLevelsFluorescentW", &stdInterpreter}, + {0, 1, 0, 0, 0x0214, "WB_RGGBLevelsFlash", &stdInterpreter}, + {0, 1, 0, pentaxCameraInfoAttribs, 0x0215, "CameraInfo", &stdInterpreter}, + {0, 1, 0, pentaxBatteryInfoAttribs, 0x0216, "BatteryInfo", &stdInterpreter}, + {0, 1, 0, 0, 0x021f, "AFInfo", &stdInterpreter}, + {0, 1, 0, 0, 0x0222, "ColorInfo", &stdInterpreter}, + {0, 1, 0, 0, 0x03fe, "DataDump", &stdInterpreter}, + {0, 1, 0, 0, 0x03ff, "UnknownInfo", &stdInterpreter}, + {0, 1, 0, 0, 0x0402, "ToneCurve", &stdInterpreter}, + {0, 1, 0, 0, 0x0403, "ToneCurves", &stdInterpreter}, + {0, 1, 0, 0, 0x0e00, "PrintIM", &stdInterpreter}, + {-1, 0, 0, 0, 0, "", NULL}}; + +const TagAttrib pentaxSRInfoAttribs[] = { + {0, 1, 0, 0, 0, "SRResult", &paSRResultInterpreter}, + {0, 1, 0, 0, 1, "ShakeReduction", &paOnOffInterpreter}, + {0, 1, 0, 0, 2, "SRHalfPressTime", &stdInterpreter}, + {0, 1, 0, 0, 3, "SRFocalLength", &stdInterpreter}, + {-1, 0, 0, 0, 0, "", NULL}}; + +const TagAttrib pentaxLensDataAttribs[] = { + {0, 1, 0, 0, 10, "NominalMinMaxAperture", &paNominalMinMaxApertureInterpreter}, + {0, 1, 0, 0, 14, "MaxAperture", &paMaxApertureInterpreter}, + {-1, 0, 0, 0, 0, "", NULL}}; + +const TagAttrib pentaxCameraSettingsAttribs[] = { + {0, 1, 0, 0, 0, "PictureMode2", &paPictureMode2Interpreter}, + {0, 1, 0, 0, 1, "ProgramLine", &paProgramLineInterpreter}, + {0, 1, 0, 0, 1, "EVSteps", &paEVStepsInterpreter}, + {0, 1, 0, 0, 1, "E-DialinProgram", &paEDialinInterpreter}, + {0, 1, 0, 0, 1, "ApertureRing", &paApertureRingUseInterpreter}, + {0, 1, 0, 0, 2, "FlashOptions", &paFlashOptionInterpreter}, + {0, 1, 0, 0, 2, "MeteringMode2", &paMeteringMode2Interpreter}, + {0, 1, 0, 0, 3, "AFMode", &paAFModeInterpreter}, + {0, 1, 0, 0, 4, "AFPointSelected2", &paAFPointSelectedInterpreter}, + {0, 1, 0, 0, 7, "DriveMode2", &paDriveMode2Interpreter}, + {0, 1, 0, 0, 8, "ExposureBracketStepSize", &paExposureBracketStepSizeInterpreter}, + {0, 1, 0, 0, 9, "BracketShotNumber", &stdInterpreter}, + {0, 1, 0, 0, 10, "WhiteBalanceSet", &stdInterpreter}, + {-1, 0, 0, 0, 0, "", NULL}}; + +const TagAttrib pentaxAEInfoAttribs[] = { + {0, 1, 0, 0, 0, "AEExposureTime", &stdInterpreter}, + {0, 1, 0, 0, 1, "AEAperture", &stdInterpreter}, + {0, 1, 0, 0, 2, "AE_ISO", &stdInterpreter}, + {0, 1, 0, 0, 3, "AEXv", &stdInterpreter}, + {0, 1, 0, 0, 4, "AEBXv", &stdInterpreter}, + {0, 1, 0, 0, 5, "AEMinExposureTime", &stdInterpreter}, + {0, 1, 0, 0, 6, "AEProgramMode", &stdInterpreter}, + {0, 1, 0, 0, 9, "AEMaxAperture", &stdInterpreter}, + {0, 1, 0, 0, 10, "AEMaxAperture2", &stdInterpreter}, + {0, 1, 0, 0, 11, "AEMinAperture", &stdInterpreter}, + {0, 1, 0, 0, 12, "AEMeteringMode", &stdInterpreter}, + {0, 1, 0, 0, 14, "FlashExposureCompSet", &stdInterpreter}, + {-1, 0, 0, 0, 0, "", NULL}}; + +const TagAttrib pentaxFlashInfoAttribs[] = { + {0, 1, 0, 0, 0, "FlashStatus", &paFlashStatusInterpreter}, + {0, 1, 0, 0, 1, "InternalFlashMode", &paInternalFlashModeInterpreter}, + {0, 1, 0, 0, 2, "ExternalFlashMode", &paExternalFlashModeInterpreter}, + {0, 1, 0, 0, 3, "InternalFlashStrength", &stdInterpreter}, + {0, 1, 0, 0, 24, "ExternalFlashGuideNumber", &paExternalFlashGNInterpreter}, + {0, 1, 0, 0, 25, "ExternalFlashExposureComp", &paExternalFlashExposureCompInterpreter}, + {0, 1, 0, 0, 26, "ExternalFlashBounce", &paExternalFlashBounceInterpreter}, + {-1, 0, 0, 0, 0, "", NULL}}; + +const TagAttrib pentaxBatteryInfoAttribs[] = { + {0, 1, 0, 0, 0, "PowerSource", &paPowerSourceInterpreter}, + {0, 1, 0, 0, 1, "BatteryStates", &stdInterpreter}, + {0, 1, 0, 0, 2, "BatteryADBodyNoLoad", &stdInterpreter}, + {0, 1, 0, 0, 3, "BatteryADBodyLoad", &stdInterpreter}, + {0, 1, 0, 0, 4, "BatteryADGripNoLoad", &stdInterpreter}, + {0, 1, 0, 0, 5, "BatteryADGripLoad", &stdInterpreter}, + {-1, 0, 0, 0, 0, "", NULL}}; + +const TagAttrib pentaxCameraInfoAttribs[] = { + {0, 1, 0, 0, 0, "PentaxModelID", &stdInterpreter}, + {0, 1, 0, 0, 1, "ManufactureDate", &stdInterpreter}, + {0, 1, 0, 0, 2, "ProductionCode", &stdInterpreter}, + {0, 1, 0, 0, 4, "InternalSerialNumber", &stdInterpreter}, + {-1, 0, 0, 0, 0, "", NULL}}; + +} +#endif + + + + diff --git a/rtexif/rtexif.cc b/rtexif/rtexif.cc new file mode 100644 index 000000000..9bab4de2b --- /dev/null +++ b/rtexif/rtexif.cc @@ -0,0 +1,1935 @@ +/* + * 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 "rtexif.h" + +using namespace std; + +namespace rtexif { + +StdInterpreter 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>200) + 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; +} + +void TagDirectory::printAll () const { + + for (size_t i=0; inameToString (); + if (tags[i]->isDirectory()) + for (int j=0; tags[i]->getDirectory(j); j++) { + printf ("==== DIRECTORY %s[%d]: ====\n", name.c_str(), j); + tags[i]->getDirectory(j)->printAll (); + printf ("==== END OF DIRECTORY %s[%d] ====\n", name.c_str(), j); + } + else { + std::string value = tags[i]->valueToString (); + printf ("%s: %s\n", name.c_str(), value.c_str()); + } + } +} + +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::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)),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)),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) { + + tag = get2 (f, getOrder()); + type = (TagType)get2 (f, getOrder()); + count = get4 (f, getOrder()); + + makerNoteKind = NOMK; + keep = false; + + // filter out invalid tags + if ((int)type<1 || (int)type>14 || count>900000) { + type = INVALID; + return; + } + + // save file position + 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==1 || attrib->action==3)) + keep = true; + + // if this tag is the makernote, it needs special treatment (brand specific parsing) + if (tag==0x927C && attrib && !strcmp (attrib->name, "MakerNote")) { + value = NULL; + // select format of makernote + char make[128], model[128]; + Tag* tmake = parent->getParent()->getTag ("Make"); + if (tmake) + tmake->toString (make); + else + make[0] = 0; + Tag* tmodel = parent->getParent()->getTag ("Model"); + if (tmodel) + tmodel->toString (model); + else + model[0] = 0; + if (!strncmp(make, "NIKON", 5)) { + if (!strncmp(model, "NIKON E700",10)||!strncmp(model, "NIKON E800",10)||!strncmp(model, "NIKON E900",10)||!strncmp(model, "NIKON E900S",11)||!strncmp(model, "NIKON E910", 10)||!strncmp(model, "NIKON E950", 10)) { + 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, getOrder()); + directory[1] = NULL; + } + else if (!strncmp(model, "NIKON E990",10)||(!strncmp(model, "NIKON D1",8) && model[8]!='0')) { + makerNoteKind = IFD; + directory = new TagDirectory*[2]; + directory[0] = new TagDirectory (parent, f, base, nikon3Attribs, getOrder()); + 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, getOrder()); + directory[1] = NULL; + } + } + else if (!strncmp(make, "Canon", 5)) { + makerNoteKind = IFD; + directory = new TagDirectory*[2]; + directory[0] = new TagDirectory (parent, f, base, canonAttribs, getOrder()); + directory[1] = NULL; + } + else if (!strncmp(make, "PENTAX", 6)) { + 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, getOrder()); + directory[1] = NULL; + } + else if (!strncmp(make, "FUJIFILM", 8)) { + 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 (!strncmp(make, "KONICA MINOLTA", 14) || !strncmp(make, "Minolta", 7)) { + makerNoteKind = IFD; + directory = new TagDirectory*[2]; + directory[0] = new TagDirectory (parent, f, base, minoltaAttribs, getOrder()); + directory[1] = NULL; + } + else if (!strncmp(make, "SONY", 4)) { + 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, getOrder()); + directory[1] = NULL; + } + else if (!strncmp(make, "OLYMPUS", 7)) { + 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, getOrder()); + } + else { + 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]; + Tag* tmake = parent->getRoot()->getTag ("Make"); + if (tmake) tmake->toString (make); + else make[0] = 0; + Tag* tmodel = parent->getRoot()->getTag ("Model"); + if (tmodel) tmodel->toString (model); + else model[0] = 0; + + + if (!strncmp(make, "SONY", 4)) { + switch( tag ){ + case 0x0114: + { + directory = new TagDirectory*[2]; + directory[1] = NULL; + if( strstr(model, "A330") || strstr(model, "A380") ) + directory[0] = new TagDirectoryTable (parent, f, valuesize*2,0,SHORT , sonyCameraSettingsAttribs2, MOTOROLA); + else + directory[0] = new TagDirectoryTable (parent, f, valuesize*2,0,SHORT , sonyCameraSettingsAttribs, MOTOROLA); + 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, getOrder()); + makerNoteKind = TABLESUBDIR; + break; + case 0x0215: + directory = new TagDirectory*[2]; + directory[1] = NULL; + directory[0] = new TagDirectoryTable (parent, f, valuesize,0,LONG , attrib->subdirAttribs, getOrder()); + makerNoteKind = TABLESUBDIR; + break; + case 0x0207: + { // There are 2 format pentaxLensDataAttribs + int offsetFirst = 4; + if( strstr(model, "*ist") || strstr(model, "GX-1") || strstr(model, "K100D") || strstr(model, "K110D") ) + offsetFirst = 3; + if( strstr(model, "K-5") || strstr(model, "K-r") ) + offsetFirst = 12; + directory = new TagDirectory*[2]; + directory[1] = NULL; + directory[0] = new TagDirectoryTable (parent, f, valuesize,offsetFirst,BYTE , attrib->subdirAttribs, getOrder()); + 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, getOrder()); + 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, getOrder()); + 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, getOrder()); + 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, getOrder()); + 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; + +} + +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) { + + 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) { + 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.; +} + +void Tag::toRational (int& num, int& denom, int ofs) { + + switch (type) { + case BYTE: num = (int)value[ofs]; denom = 1; break; + case ASCII: num = 0; denom = 0; break; + case SSHORT: + case SHORT: num = (int)sget2 (value+ofs, getOrder()); denom = 1; break; + case SLONG: + case LONG: num = (int)sget4 (value+ofs, getOrder()); denom = 1; break; + case SRATIONAL: + case RATIONAL: num = (int)sget4 (value+ofs, getOrder()); denom = (int)sget4 (value+ofs+4, getOrder()); break; + case FLOAT: num = 0; denom = 0; break; + case UNDEFINED: num = 0; denom = 0; break; + default: num = 0; denom = 0; // Quick fix for missing cases (INVALID, DOUBLE, OLYUNDEF, SUBDIR) + } +} + +void Tag::toString (char* buffer, int ofs) { + + if (type==UNDEFINED && !directory) { + bool isstring = true; + int i=0; + for (i=0; i+ofs126) + 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==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::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; + 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.0); + fnumber = pow (2, aperture/2); + shutter = ((short)get2(f, INTEL))/32.0; + ev = ((short)get2(f, INTEL))/32.0; + fseek (f, 34, SEEK_CUR); + if (shutter > 1e6) shutter = get2 (f, INTEL) / 10.0; + 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". + 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", 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", 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", 4) == 0 || + strncmp(&val[1], "PKTS", 4) == 0 || + strncmp(&val[2], "PKTS", 4) == 0 || + strncmp(&val[3], "PKTS", 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) + { + 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) { + t->initInt (atoi(val), 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, "%02d:%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); + } + } + } + + 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]; +} + +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); + return true; + } + } + return false; +} + +} diff --git a/rtexif/rtexif.h b/rtexif/rtexif.h new file mode 100644 index 000000000..185aee9fc --- /dev/null +++ b/rtexif/rtexif.h @@ -0,0 +1,369 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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 "../rtengine/procparams.h" + +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, SUBDIR=99}; +enum ActionCode {DONTWRITE=0, WRITE=1, SYSTEM=2}; +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); + +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 + int action; //=0: dont write it to the output, =1: write it to the output, =2: dont write, dont show, =3: write, dont show + int editable; + const TagAttrib* subdirAttribs; // =0 ->not subdir + unsigned short ID; // Numeric identifier of tag (or index inside DirectoryTable) + const char* name; + Interpreter* interpreter; +}; + +// 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) + + 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); + const TagAttrib* getAttribTable() { return attribs; } + virtual Tag* getTag (const char* name) const; + virtual 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 () 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; + + 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 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 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); + 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 confortable 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[i]; } + + 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 std::string toString (Tag* t) { return ""; } + virtual void fromString (Tag* t, const std::string& value) {} +}; + +class StdInterpreter : public Interpreter { + public: + StdInterpreter () {} + 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()); + } +}; +extern StdInterpreter 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 ) + { + 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; + } + + + double deltaMin = 1000.; + + /* 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::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( 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 ); +inline unsigned short sget2 (unsigned char *s, ByteOrder order); +inline 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); +inline short int int2_to_signed (short unsigned int i); + +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 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 sonyCameraSettingsAttribs[]; +extern const TagAttrib sonyCameraSettingsAttribs2[]; +extern const TagAttrib olympusAttribs[]; +} +#endif diff --git a/rtexif/sonyminoltaattribs.cc b/rtexif/sonyminoltaattribs.cc new file mode 100644 index 000000000..f386b7bec --- /dev/null +++ b/rtexif/sonyminoltaattribs.cc @@ -0,0 +1,950 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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 SAOnOffInterpreter : public ChoiceInterpreter { + public: + SAOnOffInterpreter () { + choices[0] = "Off"; + choices[1] = "On"; + choices[5] = "On"; + } +}; +SAOnOffInterpreter saOnOffInterpreter; + +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 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 () { + 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(5, "Minolta AF 35-70mm f/3.5-4.5")); + choices.insert(p_t(6, "Minolta AF 24-85mm f/3.5-4.5 [New]")); + choices.insert(p_t(7, "Minolta AF 100-300mm f/4.5-5.6 APO [New]")); + 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")); + choices.insert(p_t(20, "Minolta/Sony STF 135mm F2.8 [T4.5]")); + choices.insert(p_t(22, "Minolta AF 35-80mm f/4-5.6")); + choices.insert(p_t(23, "Minolta AF 200mm f/4 G APO Macro")); + 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, "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 DG")); + choices.insert(p_t(27, "Minolta AF 85mm f71.4 G")); + choices.insert(p_t(28, "Minolta 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(29, "Minolta 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 10-20mm f/4-5.6 EX DC")); + choices.insert(p_t(30, "Sigma 12-24mm f/4.5-5.6 EX DG")); + choices.insert(p_t(30, "Sigma 28-70mm f/2.8 EX DG")); + 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(32, "Minolta AF 300mm f/2.8 G")); + choices.insert(p_t(33, "Minolta/Sony AF 70-200mm f/2.8 G (D) SSM")); + 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(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 or 55-200mm f/4-5.5")); + choices.insert(p_t(52, "Sony AF 70-300mm f/4.5-5.6 G SSM")); + 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(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 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")); + choices.insert(p_t(128, "Sigma 70-200mm f/2.8 II EX DG APO Macro")); + 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(129, "Tamron 200-400mm f/5.6 LD (IF)")); + 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")); + 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 [New]")); + 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(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(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 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(25621, "Minolta AF 50mm f/1.4")); + choices.insert(p_t(25631, "Minolta AF 300mm f/2.8 G")); + 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 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(25721, "Minolta/Sony AF 500mm f/8 Reflex")); + choices.insert(p_t(25781, "Minolta 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 AF 20mm f/2.8")); + choices.insert(p_t(25811, "Minolta/Sony AF 100mm f/2.8 Macro New")); + 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, "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 New")); + 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-200 f/2.8 APO")); + choices.insert(p_t(25891, "Tokina 80-200mm f/2.8")); + 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(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 (D)")); + 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 Power Zoom")); + choices.insert(p_t(26161, "Minolta AF 35-200mm f/4.5-5.6 Power Zoom")); + choices.insert(p_t(26181, "Minolta AF 28-80mm f/4-5.6 Power Zoom")); + choices.insert(p_t(26191, "Minolta AF 80-200mm f/4.5-5.6 Power Zoom")); + 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 Power Zoom")); + 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 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, "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 SP AF 70-210mm f/2.8 LD")); + 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 *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(); + return guess( lensID, focalLength, maxApertureAtFocal ); + } +}; +SALensIDInterpreter saLensIDInterpreter; + +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 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 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 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 SALocalAFAreaPoint: public ChoiceInterpreter { + public: + SALocalAFAreaPoint () { + 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"; + } +}; +SALocalAFAreaPoint saLocalAFAreaPoint; + +class SAMeteringMode: public ChoiceInterpreter { + public: + SAMeteringMode () { + choices[1] = "Multi-segment"; + choices[2] = "Center-weighted Average"; + choices[4] = "Spot"; + } +}; +SAMeteringMode saMeteringMode; + +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 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"; + choices[16] = "Sepia"; + } +}; +SACreativeStyle saCreativeStyle; + +class SAFlashMode: public ChoiceInterpreter { + public: + SAFlashMode () { + choices[0] = "ADI"; + choices[1] = "TTL"; + } +}; +SAFlashMode saFlashMode; + +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 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 SAAspectRatio: public ChoiceInterpreter { + public: + SAAspectRatio () { + choices[1] = "3:2"; + choices[2] = "16:9"; + } +}; +SAAspectRatio saAspectRatio; + +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 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; + +const TagAttrib minoltaAttribs[] = { + {0, 1, 0, 0, 0x0000, "MakerNoteVersion", &stdInterpreter}, + {0, 1, 0, 0, 0x0001, "MinoltaCameraSettingsOld", &stdInterpreter}, + {0, 1, 0, 0, 0x0003, "MinoltaCameraSettings", &stdInterpreter}, + {0, 1, 0, 0, 0x0004, "MinoltaCameraSettings7D", &stdInterpreter}, + {0, 1, 0, 0, 0x0018, "ImageStabilization", &stdInterpreter}, + {0, 1, 0, 0, 0x0040, "CompressedImageSize", &stdInterpreter}, + {1, 1, 0, 0, 0x0081, "PreviewImage", &stdInterpreter}, + {1, 1, 0, 0, 0x0088, "PreviewImageStart", &stdInterpreter}, + {1, 1, 0, 0, 0x0089, "PreviewImageLength", &stdInterpreter}, + {0, 1, 0, 0, 0x0100, "SceneMode", &saSceneModeInterpreter}, + {0, 1, 0, 0, 0x0101, "ColorMode", &saColorModeInterpreter}, + {0, 1, 0, 0, 0x0102, "MinoltaQuality", &maQualityInterpreter}, + {0, 1, 0, 0, 0x0103, "MinoltaImageSize", &maImageSizeInterpreter}, + {0, 1, 0, 0, 0x0104, "FlashExposureComp", &stdInterpreter}, + {0, 1, 0, 0, 0x0105, "Teleconverter", &maTeleconverterInterpreter}, + {0, 1, 0, 0, 0x0107, "ImageStabilization", &saOnOffInterpreter}, + {0, 1, 0, 0, 0x010a, "ZoneMatching", &saZoneMatchingInterpreter}, + {0, 1, 0, 0, 0x010b, "ColorTemperature", &stdInterpreter}, + {0, 1, 0, 0, 0x010c, "LensID", &saLensIDInterpreter}, + {0, 1, 0, 0, 0x0113, "ImageStabilization", &saOnOffInterpreter}, + {0, 1, 0, 0, 0x0114, "MinoltaCameraSettings", &stdInterpreter}, + {1, 1, 0, 0, 0x0e00, "PrintIM", &stdInterpreter}, + {0, 1, 0, 0, 0x0f00, "MinoltaCameraSettings2", &stdInterpreter}, + {-1, 0, 0, 0, 0, "", NULL}}; + +const TagAttrib sonyAttribs[] = { + {0, 1, 0, 0, 0x0102, "Quality", &maQualityInterpreter}, + {0, 1, 0, 0, 0x0104, "FlashExposureComp",&stdInterpreter}, + {0, 1, 0, 0, 0x0106, "TeleConverter", &maTeleconverterInterpreter}, + {0, 1, 0, sonyCameraSettingsAttribs, 0x0114, "SonyCameraSettings",&stdInterpreter}, + {0, 1, 0, 0, 0x0115, "WhiteBalance",&saWhiteBalanceInterpreter}, + {1, 1, 0, 0, 0x0e00, "PrintIM", &stdInterpreter}, + {1, 1, 0, 0, 0x2001, "PreviewImage", &stdInterpreter}, + {0, 1, 0, 0, 0x2009, "HighISONoiseReduction", &stdInterpreter}, + {0, 1, 0, 0, 0x200a, "AutoHDR", &stdInterpreter}, + {0, 1, 0, 0, 0x200b, "MultiFrameNoiseReduction", &stdInterpreter}, + {0, 1, 0, 0, 0x200e, "PictureEffect", &saPictureEffectInterpreter}, + {0, 1, 0, 0, 0x2011, "VignettingCorrection", &stdInterpreter}, + {0, 1, 0, 0, 0x2012, "LateralChromaticAberration", &stdInterpreter}, + {0, 1, 0, 0, 0x2013, "DistortionCorrection", &stdInterpreter}, + {0, 1, 0, 0, 0xb020, "ColorReproduction", &stdInterpreter}, + {0, 1, 0, 0, 0xb021, "ColorTemperature", &stdInterpreter}, + {0, 1, 0, 0, 0xb022, "ColorCompensationFilter", &stdInterpreter}, + {0, 1, 0, 0, 0xb023, "SceneMode", &saSceneModeInterpreter}, + {0, 1, 0, 0, 0xb024, "ZoneMatching", &saZoneMatchingInterpreter}, + {0, 1, 0, 0, 0xb025, "DynamicRangeOptimizer", &saDynamicRangeOptimizerInterpreter}, + {0, 1, 0, 0, 0xb026, "ImageStabilization", &saOnOffInterpreter}, + {0, 1, 0, 0, 0xb027, "LensID", &saLensIDInterpreter}, + {0, 1, 0, minoltaAttribs, 0xb028, "MinoltaMakerNote", &stdInterpreter}, + {0, 1, 0, 0, 0xb029, "ColorMode", &saColorModeInterpreter}, + {0, 1, 0, 0, 0xb040, "Macro", &saOnOffInterpreter}, + {0, 1, 0, 0, 0xb041, "ExposureMode", &saExposureModeInterpreter}, + {0, 1, 0, 0, 0xb042, "FocusMode", &saFocusMode}, + {0, 1, 0, 0, 0xb043, "AFMode", &saAFMode}, + {0, 1, 0, 0, 0xb044, "AFIlluminator", &saAFIlluminator}, + {0, 1, 0, 0, 0xb047, "Quality", &saQualityInterpreter}, + {0, 1, 0, 0, 0xb048, "FlashLevel", &stdInterpreter}, + {0, 1, 0, 0, 0xb049, "ReleaseMode",&saReleaseModeInterpreter}, + {0, 1, 0, 0, 0xb04a, "SequenceNumber", &stdInterpreter}, + {0, 1, 0, 0, 0xb04b, "AntiBlur", &saAntiBlurInterpreter}, + {0, 1, 0, 0, 0xb04e, "LongExposureNoiseReduction", &saOnOffInterpreter}, + {0, 1, 0, 0, 0xb04f, "DynamicRangeOptimizer", &stdInterpreter}, + {0, 1, 0, 0, 0xb052, "IntelligentAuto", &stdInterpreter}, + {-1, 0, 0, 0, 0, "", NULL}}; + +const TagAttrib sonyCameraSettingsAttribs[]={ + {0, 1, 0, 0, 4, "DriveMode", &saDriveMode}, + {0, 1, 0, 0, 6, "WhiteBalanceFineTune",&stdInterpreter}, + {0, 1, 0, 0, 16, "FocusMode",&saFocusMode}, + {0, 1, 0, 0, 17, "AFAreaMode",&saAFAreaMode}, + {0, 1, 0, 0, 18, "LocalAFAreaPoint", &saLocalAFAreaPoint}, + {0, 1, 0, 0, 21, "MeteringMode",&saMeteringMode}, + {0, 1, 0, 0, 22, "ISOSetting",&stdInterpreter}, + {0, 1, 0, 0, 24, "DynamicRangeOptimizerMode", &saDynamicRangeOptimizerMode}, + {0, 1, 0, 0, 25, "DynamicRangeOptimizerLevel",&stdInterpreter}, + {0, 1, 0, 0, 26, "CreativeStyle",&saCreativeStyle}, + {0, 1, 0, 0, 28, "Sharpness",&stdInterpreter}, + {0, 1, 0, 0, 29, "Contrast",&stdInterpreter}, + {0, 1, 0, 0, 30, "Saturation",&stdInterpreter}, + {0, 1, 0, 0, 31, "ZoneMatchingValue",&stdInterpreter}, + {0, 1, 0, 0, 34, "Brightness",&stdInterpreter}, + {0, 1, 0, 0, 35, "FlashMode",&saFlashMode}, + {0, 1, 0, 0, 40, "PrioritySetupShutterRelease",&stdInterpreter}, + {0, 1, 0, 0, 41, "AFIlluminator",&saAFIlluminator}, + {0, 1, 0, 0, 42, "AFWithShutter",&saOnOffInterpreter}, + {0, 1, 0, 0, 43, "LongExposureNoiseReduction",&saOnOffInterpreter}, + {0, 1, 0, 0, 44, "HighISONoiseReduction",&stdInterpreter}, + {0, 1, 0, 0, 45, "ImageStyle",&saImageStyleInterpreter}, + {0, 1, 0, 0, 60, "ExposureProgram",&saExposureProgram}, + {0, 1, 0, 0, 61, "ImageStabilization",&saOnOffInterpreter}, + {0, 1, 0, 0, 63, "Rotation",&saRotation}, + {0, 1, 0, 0, 84, "SonyImageSize",&saSonyImageSize}, + {0, 1, 0, 0, 85, "AspectRatio",&saAspectRatio}, + {0, 1, 0, 0, 86, "Quality",&saQualityInterpreter2}, + {0, 1, 0, 0, 88, "ExposureLevelIncrements",&saExposureLevelIncrements}, + {-1, 0, 0, 0, 0, "", NULL}}; + +const TagAttrib sonyCameraSettingsAttribs2[]={ + {0, 1, 0, 0, 16, "FocusMode",&saFocusMode}, + {0, 1, 0, 0, 17, "AFAreaMode",&saAFAreaMode}, + {0, 1, 0, 0, 18, "LocalAFAreaPoint",&saLocalAFAreaPoint}, + {0, 1, 0, 0, 19, "MeteringMode",&saMeteringMode}, + {0, 1, 0, 0, 20, "ISOSetting",&stdInterpreter}, + {0, 1, 0, 0, 22, "DynamicRangeOptimizerMode",&saDynamicRangeOptimizerMode}, + {0, 1, 0, 0, 23, "DynamicRangeOptimizerLevel",&stdInterpreter}, + {0, 1, 0, 0, 24, "CreativeStyle",&saCreativeStyle}, + {0, 1, 0, 0, 25, "Sharpness",&stdInterpreter}, + {0, 1, 0, 0, 26, "Contrast",&stdInterpreter}, + {0, 1, 0, 0, 27, "Saturation",&stdInterpreter}, + {0, 1, 0, 0, 35, "FlashMode",&saFlashMode}, + {0, 1, 0, 0, 60, "ExposureProgram",&saExposureProgram}, + {0, 1, 0, 0, 63, "Rotation",&saRotation}, + {0, 1, 0, 0, 84, "SonyImageSize",&saSonyImageSize}, + {-1, 0, 0, 0, 0, "", NULL}}; +} +#endif + + diff --git a/rtexif/stdattribs.cc b/rtexif/stdattribs.cc new file mode 100644 index 000000000..06aacf9fd --- /dev/null +++ b/rtexif/stdattribs.cc @@ -0,0 +1,561 @@ +/* + * 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 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 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[1024]; + if (!strncmp((char*)t->getValue(), "ASCII\0\0\0",8)) + strncpy (buffer, (char*)t->getValue()+8, t->getCount()-8); + else + buffer[0]=0; + return buffer; + } + virtual void fromString (Tag* t, const std::string& value) { + char buffer[1024]; + memcpy (buffer, "ASCII\0\0\0", 8); + strcpy (buffer+8, value.c_str()); + t->fromString (buffer, value.size() + 9); + } +}; +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"; + } +}; +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, 2, 0, 0, 0x0100, "ImageWidth", &stdInterpreter}, + {0, 2, 0, 0, 0x0101, "ImageHeight", &stdInterpreter}, + {0, 2, 0, 0, 0x0102, "BitsPerSample", &stdInterpreter}, + {0, 2, 0, 0, 0x0103, "Compression", &compressionInterpreter}, + {0, 1, 0, 0, 0x828d, "CFAPatternDim", &stdInterpreter}, + {0, 1, 0, 0, 0x828e, "CFAPattern", &cfaInterpreter}, + {0, 1, 0, 0, 0x829A, "ExposureTime", &exposureTimeInterpreter}, + {0, 1, 0, 0, 0x829D, "FNumber", &fNumberInterpreter}, + {0, 1, 0, 0, 0x8822, "ExposureProgram", &exposureProgramInterpreter}, + {0, 1, 0, 0, 0x8824, "SpectralSensitivity", &stdInterpreter}, + {0, 1, 0, 0, 0x8827, "ISOSpeedRatings", &stdInterpreter}, + {0, 1, 0, 0, 0x8828, "OECF", &stdInterpreter}, + {0, 1, 0, 0, 0x9000, "ExifVersion", &stdInterpreter}, + {0, 1, 0, 0, 0x9003, "DateTimeOriginal", &stdInterpreter}, + {0, 1, 0, 0, 0x9004, "DateTimeDigitized", &stdInterpreter}, + {0, 2, 0, 0, 0x9101, "ComponentsConfiguration", &stdInterpreter}, + {0, 2, 0, 0, 0x9102, "CompressedBitsPerPixel", &stdInterpreter}, + {0, 1, 0, 0, 0x9201, "ShutterSpeedValue", &shutterSpeedInterpreter}, + {0, 1, 0, 0, 0x9202, "ApertureValue", &apertureInterpreter}, + {0, 1, 0, 0, 0x9203, "BrightnessValue", &stdInterpreter}, + {0, 1, 0, 0, 0x9204, "ExposureBiasValue", &exposureBiasInterpreter}, + {0, 1, 0, 0, 0x9205, "MaxApertureValue", &apertureInterpreter}, + {0, 1, 0, 0, 0x9206, "SubjectDistance", &stdInterpreter}, + {0, 1, 0, 0, 0x9207, "MeteringMode", &meteringModeInterpreter}, + {0, 1, 0, 0, 0x9208, "LightSource", &lightSourceInterpreter}, + {0, 1, 0, 0, 0x9209, "Flash", &flashInterpreter}, + {0, 1, 0, 0, 0x920A, "FocalLength", &focalLengthInterpreter}, + {0, 1, 0, 0, 0x9214, "SubjectArea", &stdInterpreter}, + {0, 0, 0, 0, 0x9216, "TIFFEPSStandardID", &stdInterpreter}, + {0, 1, 0, 0, 0x9217, "SensingMethod", &stdInterpreter}, + {0, 1, 0, 0, 0x927C, "MakerNote", &stdInterpreter}, + {0, 1, 1, 0, 0x9286, "UserComment", &userCommentInterpreter}, + {0, 1, 0, 0, 0x9290, "SubSecTime", &stdInterpreter}, + {0, 1, 0, 0, 0x9291, "SubSecTimeOriginal", &stdInterpreter}, + {0, 1, 0, 0, 0x9292, "SubSecTimeDigitized", &stdInterpreter}, + {0, 2, 0, 0, 0xA000, "FlashpixVersion", &stdInterpreter}, + {0, 0, 0, 0, 0xA001, "ColorSpace", &colorSpaceInterpreter}, + {0, 2, 0, 0, 0xA002, "PixelXDimension", &stdInterpreter}, + {0, 2, 0, 0, 0xA003, "PixelYDimension", &stdInterpreter}, + {1, 0, 0, 0, 0xA004, "RelatedSoundFile", &stdInterpreter}, + {0, 2, 0, iopAttribs, 0xA005, "Interoperability", &stdInterpreter}, // do not enable, as it causes trouble with FUJI files + {0, 1, 0, 0, 0xA20B, "FlashEnergy", &stdInterpreter}, + {0, 1, 0, 0, 0xA20C, "SpatialFrequencyResponse", &stdInterpreter}, + {0, 1, 0, 0, 0xA20E, "FocalPlaneXResolution", &stdInterpreter}, + {0, 1, 0, 0, 0xA20F, "FocalPlaneYResolution", &stdInterpreter}, + {0, 1, 0, 0, 0xA210, "FocalPlaneResolutionUnit", &stdInterpreter}, + {0, 1, 0, 0, 0xA214, "SubjectLocation", &stdInterpreter}, + {0, 1, 0, 0, 0xA215, "ExposureIndex", &stdInterpreter}, + {0, 1, 0, 0, 0xA217, "SensingMethod", &stdInterpreter}, + {0, 1, 0, 0, 0xA300, "FileSource", &stdInterpreter}, + {0, 1, 0, 0, 0xA301, "SceneType", &stdInterpreter}, + {0, 0, 0, 0, 0xA302, "CFAPattern", &cfaInterpreter}, + {0, 1, 0, 0, 0xA401, "CustomRendered", &stdInterpreter}, + {0, 1, 0, 0, 0xA402, "ExposureMode", &exposureModeInterpreter}, + {0, 1, 0, 0, 0xA403, "WhiteBalance", &whiteBalanceInterpreter}, + {0, 1, 0, 0, 0xA404, "DigitalZoomRatio", &stdInterpreter}, + {0, 1, 0, 0, 0xA405, "FocalLengthIn35mmFilm", &stdInterpreter}, + {0, 1, 0, 0, 0xA406, "SceneCaptureType", &sceneCaptureInterpreter}, + {0, 1, 0, 0, 0xA407, "GainControl", &gainControlInterpreter}, + {0, 1, 0, 0, 0xA408, "Contrast", &contrastInterpreter}, + {0, 1, 0, 0, 0xA409, "Saturation", &saturationInterpreter}, + {0, 1, 0, 0, 0xA40A, "Sharpness", &sharpnessInterpreter}, + {0, 1, 0, 0, 0xA40B, "DeviceSettingDescription", &stdInterpreter}, + {0, 1, 0, 0, 0xA40C, "SubjectDistanceRange", &stdInterpreter}, + {0, 1, 0, 0, 0xA420, "ImageUniqueID", &stdInterpreter}, + {0, 1, 0, 0, 0xA431, "SerialNumber", &stdInterpreter}, + {0, 1, 0, 0, 0xA432, "LensInfo", &stdInterpreter}, + {0, 1, 0, 0, 0xA433, "LensMake", &stdInterpreter}, + {0, 1, 0, 0, 0xA434, "LensModel", &stdInterpreter}, + {0, 1, 0, 0, 0xA435, "LensSerialNumber", &stdInterpreter}, + {0, 1, 0, 0, 0xc630, "DNGLensInfo", &stdInterpreter}, + {-1, 0, 0, 0, 0, "", NULL }}; + + +const TagAttrib gpsAttribs[] = { + {0, 1, 0, 0, 0x0000, "GPSVersionID", &stdInterpreter}, + {0, 1, 0, 0, 0x0001, "GPSLatitudeRef", &stdInterpreter}, + {0, 1, 0, 0, 0x0002, "GPSLatitude", &stdInterpreter}, + {0, 1, 0, 0, 0x0003, "GPSLongitudeRef", &stdInterpreter}, + {0, 1, 0, 0, 0x0004, "GPSLongitude", &stdInterpreter}, + {0, 1, 0, 0, 0x0005, "GPSAltitudeRef", &stdInterpreter}, + {0, 1, 0, 0, 0x0006, "GPSAltitude", &stdInterpreter}, + {0, 1, 0, 0, 0x0007, "GPSTimeStamp", &stdInterpreter}, + {0, 1, 0, 0, 0x0008, "GPSSatelites", &stdInterpreter}, + {0, 1, 0, 0, 0x0009, "GPSStatus", &stdInterpreter}, + {0, 1, 0, 0, 0x000a, "GPSMeasureMode", &stdInterpreter}, + {0, 1, 0, 0, 0x000b, "GPSDOP", &stdInterpreter}, + {0, 1, 0, 0, 0x000c, "GPSSpeedRef", &stdInterpreter}, + {0, 1, 0, 0, 0x000d, "GPSSpeed", &stdInterpreter}, + {0, 1, 0, 0, 0x000e, "GPSTrackRef", &stdInterpreter}, + {0, 1, 0, 0, 0x000f, "GPSTrack", &stdInterpreter}, + {0, 1, 0, 0, 0x0010, "GPSImgDirectionRef", &stdInterpreter}, + {0, 1, 0, 0, 0x0011, "GPSImgDirection", &stdInterpreter}, + {0, 1, 0, 0, 0x0012, "GPSMapDatum", &stdInterpreter}, + {0, 1, 0, 0, 0x0013, "GPSDestLatitudeRef", &stdInterpreter}, + {0, 1, 0, 0, 0x0014, "GPSDestLatitude", &stdInterpreter}, + {0, 1, 0, 0, 0x0015, "GPSDestLongitudeRef", &stdInterpreter}, + {0, 1, 0, 0, 0x0016, "GPSDestLongitude", &stdInterpreter}, + {0, 1, 0, 0, 0x0017, "GPSDestBearingRef", &stdInterpreter}, + {0, 1, 0, 0, 0x0018, "GPSDestBearing", &stdInterpreter}, + {0, 1, 0, 0, 0x0019, "GPSDestDistanceRef", &stdInterpreter}, + {0, 1, 0, 0, 0x001a, "GPSDestDistance", &stdInterpreter}, + {0, 1, 0, 0, 0x001b, "GPSProcessingMethod", &stdInterpreter}, + {0, 1, 0, 0, 0x001c, "GPSAreaInformation", &stdInterpreter}, + {0, 1, 0, 0, 0x001d, "GPSDateStamp", &stdInterpreter}, + {0, 1, 0, 0, 0x001e, "GPSDifferential", &stdInterpreter}, + {-1, 0, 0, 0, 0, "", NULL }}; + +const TagAttrib iopAttribs[] = { + {0, 1, 0, 0, 0x0001, "InteroperabilityIndex", &stdInterpreter}, + {0, 1, 0, 0, 0x0002, "InteroperabilityVersion", &stdInterpreter}, + {-1, 0, 0, 0, 0, "", NULL }}; + + const TagAttrib ifdAttribs[] = { + {0, 2, 0, 0, 0x0017, "PanaISO", &stdInterpreter}, + {0, 2, 0, 0, 0x0100, "ImageWidth", &stdInterpreter}, + {0, 2, 0, 0, 0x0101, "ImageHeight", &stdInterpreter}, + {0, 2, 0, 0, 0x0102, "BitsPerSample", &stdInterpreter}, + {0, 2, 0, 0, 0x0103, "Compression", &compressionInterpreter}, + {0, 2, 0, 0, 0x0106, "PhotometricInterpretation", &photometricInterpreter}, + {0, 1, 1, 0, 0x010E, "ImageDescription", &stdInterpreter}, + {0, 1, 0, 0, 0x010F, "Make", &stdInterpreter}, + {0, 1, 0, 0, 0x0110, "Model", &stdInterpreter}, + {1, 0, 0, 0, 0x0111, "StripOffsets", &stdInterpreter}, + {0, 2, 0, 0, 0x0112, "Orientation", &orientationInterpreter}, + {0, 2, 0, 0, 0x0115, "SamplesPerPixel", &stdInterpreter}, + {1, 0, 0, 0, 0x0116, "RowsPerStrip", &stdInterpreter}, + {1, 0, 0, 0, 0x0117, "StripByteCounts", &stdInterpreter}, + {0, 2, 0, 0, 0x011A, "XResolution", &stdInterpreter}, + {0, 2, 0, 0, 0x011B, "YResolution", &stdInterpreter}, + {0, 2, 0, 0, 0x011C, "PlanarConfiguration", &planarConfigInterpreter}, + {0, 2, 0, 0, 0x0128, "ResolutionUnit", &unitsInterpreter}, + {0, 2, 0, 0, 0x012D, "TransferFunction", &stdInterpreter}, + {0, 2, 0, 0, 0x0131, "Software", &stdInterpreter}, + {0, 1, 0, 0, 0x0132, "DateTime", &stdInterpreter}, + {0, 1, 1, 0, 0x013B, "Artist", &stdInterpreter}, + {0, 2, 0, 0, 0x013E, "WhitePoint", &stdInterpreter}, + {0, 2, 0, 0, 0x013F, "PriomaryChromaticities", &stdInterpreter}, + {0, 1, 0, ifdAttribs, 0x014A, "SubIFD", &stdInterpreter}, + {0, 2, 0, 0, 0x0201, "JPEGInterchangeFormat", &stdInterpreter}, + {0, 2, 0, 0, 0x0202, "JPEGInterchangeFormatLength", &stdInterpreter}, + {0, 2, 0, 0, 0x0211, "YCbCrCoefficients", &stdInterpreter}, + {0, 2, 0, 0, 0x0212, "YCbCrSubSampling", &stdInterpreter}, + {0, 2, 0, 0, 0x0213, "YCbCrPositioning", &stdInterpreter}, + {0, 2, 0, 0, 0x0214, "ReferenceBlackWhite", &stdInterpreter}, + {0, 2, 0, 0, 0x02bc, "ApplicationNotes", &utf8BinInterpreter}, // XMP + {0, 1, 0, 0, 0x4746, "Rating",&stdInterpreter}, + {0, 1, 0, 0, 0x4749, "RatingPercent",&stdInterpreter}, + {0, 1, 0, 0, 0x828d, "CFAPatternDim", &stdInterpreter}, + {0, 1, 0, 0, 0x828e, "CFAPattern", &cfaInterpreter}, + {0, 1, 1, 0, 0x8298, "Copyright", &stdInterpreter}, + {0, 0, 0, 0, 0x8606, "LeafData", &stdInterpreter}, // is actually a subdir, but a proprietary format + {0, 1, 0, exifAttribs, 0x8769, "Exif", &stdInterpreter}, + {0, 2, 0, 0, 0x8773, "ICCProfile", &stdInterpreter}, + {0, 2, 0, 0, 0x83BB, "IPTCData", &stdInterpreter}, + {0, 1, 0, gpsAttribs, 0x8825, "GPSInfo", &stdInterpreter}, + {0, 1, 0, 0, 0x9003, "DateTimeOriginal", &stdInterpreter}, + {0, 1, 0, 0, 0x9004, "DateTimeDigitized", &stdInterpreter}, + {0, 1, 0, 0, 0x9211, "ImageNumber", &stdInterpreter}, + {0, 1, 0, iopAttribs, 0xA005, "Interoperability", &stdInterpreter}, + {0, 0, 0, 0, 0xC4A5, "PrintIMInformation", &stdInterpreter}, + {0, 1, 0, 0, 0xc62f, "CameraSerialNumber", &stdInterpreter}, + {0, 2, 0, 0, 0xc630, "DNGLensInfo", &stdInterpreter}, + {0, 1, 0, 0, 0xc65d, "RawDataUniqueID", &stdInterpreter}, + {0, 0, 0, 0, 0xc761, "NoiseProfile", &stdInterpreter}, + {0, 2, 0, 0, 0x00fe, "NewSubFileType", &stdInterpreter}, + {-1, 0, 0, 0, 0, "", NULL}}; +} + +#endif diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt new file mode 100644 index 000000000..0f63bceab --- /dev/null +++ b/rtgui/CMakeLists.txt @@ -0,0 +1,60 @@ + +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 hlrec.cc chmixer.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 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) + +include_directories (BEFORE "${CMAKE_CURRENT_BINARY_DIR}") + +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} ) + 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}) +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} ${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..1f47a6d68 --- /dev/null +++ b/rtgui/addsetids.h @@ -0,0 +1,55 @@ +#ifndef _ADDSETIDS_ +#define _ADDSETIDS_ + + +// UPDATE THE DEFAULT VALUE IN OPTIONS.CC 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_CHLUM 26 +#define ADDSET_DIRPYRDN_GAMMA 27 +#define ADDSET_CHMIXER 28 +#define ADDSET_PREPROCESS_GREENEQUIL 29 +#define ADDSET_PREPROCESS_LINEDENOISE 30 +#define ADDSET_RAWCACORR 31 +#define ADDSET_RAWEXPOS_LINEAR 32 +#define ADDSET_RAWEXPOS_PRESER 33 +#define ADDSET_RAWEXPOS_BLACKS 34 +#define ADDSET_SHARPENEDGE_AMOUNT 35 +#define ADDSET_SHARPENMICRO_AMOUNT 36 +#define ADDSET_SHARPENEDGE_PASS 37 +#define ADDSET_SHARPENMICRO_UNIFORMITY 38 +#define ADDSET_VIBRANCE_PASTELS 39 +#define ADDSET_VIBRANCE_SATURATED 40 +#define ADDSET_FREE_OUPUT_GAMMA 41 +#define ADDSET_FREE_OUTPUT_SLOPE 42 + +// When adding items, make sure to update ADDSET_PARAM_NUM +#define ADDSET_PARAM_NUM 43 // THIS IS USED AS A DELIMITER!! + +#endif diff --git a/rtgui/adjuster.cc b/rtgui/adjuster.cc new file mode 100644 index 000000000..de55ed34b --- /dev/null +++ b/rtgui/adjuster.cc @@ -0,0 +1,396 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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 + +extern Glib::ustring argv0; + +Adjuster::Adjuster (Glib::ustring vlabel, double vmin, double vmax, double vstep, double vdefault, bool editedcb) { + + adjusterListener = NULL; + afterReset = false; + blocked = false; + + vMin = vmin; + vMax = vmax; + vStep = vstep; + initialDefaultVal = vdefault; + 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 (2); + + hbox = Gtk::manage (new Gtk::HBox ()); + + adjustmentName = Glib::ustring(vlabel); + + if (editedcb) { + label = NULL; + editedCheckBox = Gtk::manage (new Gtk::CheckButton (adjustmentName)); + editedChange = editedCheckBox->signal_toggled().connect( sigc::mem_fun(*this, &Adjuster::editedToggled) ); + hbox->pack_start (*editedCheckBox); + } + else { + editedCheckBox = NULL; + label = Gtk::manage (new Gtk::Label (adjustmentName, Gtk::ALIGN_LEFT)); + hbox->pack_start (*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); + + spin = Gtk::manage (new MySpinButton ()); + spin->set_has_frame(false); + spin->set_name("FramelessSpinButton"); + + hbox->pack_end (*spin, Gtk::PACK_SHRINK, 0); + + 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, false, false); + pack_start (*slider, false, false); + + setLimits (vmin, vmax, vstep, vdefault); + + defaultVal = shapeValue (vdefault); + initialDefaultVal = shapeValue (vdefault); + editedState = defEditedState = 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 (Gtk::Image *imgIcon, double vmin, double vmax, double vstep, double vdefault, bool editedcb) { + + adjusterListener = NULL; + afterReset = false; + blocked = false; + + vMin = vmin; + vMax = vmax; + vStep = vstep; + initialDefaultVal = vdefault; + 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 (2); + + hbox = Gtk::manage (new Gtk::HBox ()); + + + if (editedcb) { + editedCheckBox = Gtk::manage (new Gtk::CheckButton ()); + editedChange = editedCheckBox->signal_toggled().connect( sigc::mem_fun(*this, &Adjuster::editedToggled) ); + hbox->pack_start (*editedCheckBox); + } + else + editedCheckBox = NULL; + + + 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_start (*imgIcon, Gtk::PACK_SHRINK); + + hbox->pack_end (*reset, Gtk::PACK_SHRINK, 0); + + 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); + + hbox->pack_end (*spin, Gtk::PACK_SHRINK, 0); + hbox->pack_start (*slider); + + pack_start (*hbox, false, false); + + setLimits (vmin, vmax, vstep, vdefault); + + defaultVal = shapeValue (vdefault); + initialDefaultVal = shapeValue (vdefault); + editedState = defEditedState = 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; +} + +void Adjuster::setDefault (double def) { + + defaultVal = shapeValue (def); +} + +void Adjuster::setDefaultEditedState (EditedState eState) { + + defEditedState = eState; +} + +void Adjuster::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 + slider->set_value (defaultVal); + else + // no modifier key or addMode=true : resetting to initial default value + slider->set_value (initialDefaultVal); +} + +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 (vmin, vmax); + slider->set_value (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 + 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); + } + addMode = addM; + } +} + +void Adjuster::spinChanged () { + + sliderChange.block (true); + slider->set_value (spin->get_value ()); + sliderChange.block (false); + + if (delay==0) { + if (adjusterListener!=NULL && !blocked) + adjusterListener->adjusterChanged (this, spin->get_value ()); + } + else + Glib::signal_idle().connect (sigc::mem_fun(*this, &Adjuster::notifyListener)); + + 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 (slider->get_value ()); + spinChange.block (false); + + if (delay==0) { + if (adjusterListener && !blocked) + adjusterListener->adjusterChanged (this, spin->get_value ()); + } + else + 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 (shapeValue (a)); + sliderChange.block (false); + spinChange.block (false); + afterReset = false; +} + +bool Adjuster::notifyListener () { + + if (adjusterListener!=NULL && !blocked) { + GThreadLock lock; + adjusterListener->adjusterChanged (this, spin->get_value ()); + } + return false; +} + +void Adjuster::setEnabled (bool enabled) { + + spin->set_sensitive (enabled); + slider->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 ()); +} + +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..cd9fe83e0 --- /dev/null +++ b/rtgui/adjuster.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 _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) {} +}; + + +class Adjuster : public Gtk::VBox { + + protected: + Glib::ustring adjustmentName; + Gtk::HBox* hbox; + Gtk::Label* label; + MyHScale* slider; + MySpinButton* spin; + Gtk::Button* reset; + AdjusterListener* adjusterListener; + sigc::connection delayConnection; + sigc::connection spinChange; + sigc::connection sliderChange; + sigc::connection editedChange; + bool listenerReady; + double defaultVal; // current default value (it can change when switching from ADD or SET mode) + double initialDefaultVal; // default value at construction time + EditedState editedState; + EditedState defEditedState; + int digits; + Gtk::CheckButton* editedCheckBox; + bool afterReset; + bool blocked; + bool addMode; + double vMin; + double vMax; + double vStep; + + double shapeValue (double a); + void refreshLabelStyle (); + + public: + + int delay; + + Adjuster (Glib::ustring label, double vmin, double vmax, double vstep, double vdefault, bool editedCheckBox=false); + Adjuster (Gtk::Image *imgIcon, double vmin, double vmax, double vstep, double vdefault, bool editedCheckBox=false); + virtual ~Adjuster (); + 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 + Glib::ustring getTextValue () { 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); + void setNbDisplayedChars (int nbr) { spin->set_width_chars(nbr); } + void setEditedState (EditedState eState); + EditedState getEditedState (); + void setDefaultEditedState (EditedState eState); + void showEditedCB (); + void block(bool isBlocked) { blocked = isBlocked; } + + void setAddMode(bool addM); + bool getAddMode() { return addMode; }; + void spinChanged (); + void sliderChanged (); + bool notifyListener (); + 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..5e3be8a2b --- /dev/null +++ b/rtgui/batchqueue.cc @@ -0,0 +1,645 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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 "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), 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 (); + + 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 () +{ + delete pmenu; +} + +// 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::rightClicked (ThumbBrowserEntryBase* entry) { + + pmenu->popup (3, this->eventTime); +} + +void BatchQueue::addEntries ( std::vector &entries, bool head) +{ + { + // TODO: Check for Linux + #ifdef WIN32 + Glib::RWLock::WriterLock l(entryRW); + #endif + + for( std::vector::iterator entry = entries.begin(); entry != entries.end();entry++ ){ + (*entry)->setParent (this); + (*entry)->resize (std::min(options.thumbSize, getMaxThumbnailHeight())); // 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 (); + + BatchQueueButtonSet* bqbs = new BatchQueueButtonSet (*entry); + bqbs->setButtonListener (this); + (*entry)->addButtonSet (bqbs); + } + saveBatchQueue( ); + } + + redraw(); + notifyListener (false); +} + +bool BatchQueue::saveBatchQueue( ) +{ + Glib::ustring savedQueueFile; + savedQueueFile = options.rtdir+"/batch/queue"; + FILE *f = safe_g_fopen (savedQueueFile, "wt"); + + if (f==NULL) + return false; + + // 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); + fprintf(f,"%s;%s\n", bqe->filename.c_str(),bqe->savedParamsFile.c_str() ); + } + fclose (f); + return true; +} + +void BatchQueue::loadBatchQueue( ) +{ + { + // TODO: Check for Linux +#ifdef WIN32 + Glib::RWLock::WriterLock l(entryRW); +#endif + + Glib::ustring savedQueueFile; + savedQueueFile = options.rtdir+"/batch/queue"; + FILE *f = safe_g_fopen (savedQueueFile, "rt"); + + if (f!=NULL) { + char *buffer = new char[1024]; + unsigned numLoaded=0; + while (fgets (buffer, 1024, f)){ + char *p = strchr(buffer,';' ); + if( p ){ + char *le = buffer + strlen(buffer); + while( --le > buffer && (*le == '\n' || *le == '\r') ); + std::string _source(buffer, p-buffer ); + std::string _paramsFile(p+1, (le +1)- (p+1) ); + Glib::ustring source(_source); + Glib::ustring paramsFile(_paramsFile); + + 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; + guint8* prev = NULL; + double tmpscale; + rtengine::IImage8* img = thumb->processThumbImage(pparams, prevh, tmpscale); + if (img) { + prevw = img->getWidth(); + prevh = img->getHeight(); + prev = new guint8[prevw * prevh * 3]; + memcpy(prev, img->getData(), prevw * prevh * 3); + img->free(); + } + BatchQueueEntry *entry = new BatchQueueEntry(job, pparams,source, prev, prevw, prevh, thumb); + entry->setParent(this); + entry->resize(options.thumbSize); + entry->savedParamsFile = paramsFile; + entry->selected = false; + fd.push_back(entry); + + BatchQueueButtonSet* bqbs = new BatchQueueButtonSet(entry); + bqbs->setButtonListener(this); + entry->addButtonSet(bqbs); + numLoaded++; + } + } + } + delete [] buffer; + fclose(f); + } + } + + redraw(); + notifyListener(false); +} + +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 +#ifdef WIN32 + Glib::RWLock::WriterLock 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 +#ifdef WIN32 + Glib::RWLock::WriterLock 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 +#ifdef WIN32 + Glib::RWLock::WriterLock 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 +#ifdef WIN32 + Glib::RWLock::ReaderLock 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 && !fd.empty()) { + BatchQueueEntry* next; + + { + // TODO: Check for Linux + #ifdef WIN32 + Glib::RWLock::WriterLock l(entryRW); + #endif + + next = static_cast(fd[0]); + // tag it as processing + next->processing = true; + 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 + 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); + saveFormat = options.saveFormatBatch; + fname = autoCompleteFileName (s, saveFormat.format); + } + else { // use the save-as filename with automatic completion for uniqueness + fname = autoCompleteFileName (removeExtension(processing->outFileName), getExtension(processing->outFileName)); + saveFormat = processing->saveFormat; + } + //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 "Unable to save output file"; + + 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 +#ifdef WIN32 + Glib::RWLock::WriterLock 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 + next->processing = true; + 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 + next->removeButtonSet (); + } + if (saveBatchQueue( )) { + safe_g_remove( processedParams ); + // Delete all files in directory \batch when finished, just to be sure to remove zombies + if( fd.empty() ){ + std::vector names; + Glib::ustring batchdir = 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) { + + 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(p))->redraw(); + return 0; +} + +void BatchQueue::setProgress (double p) { + + if (processing) + processing->progress = p; + + 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; +}; + +int bqnotifylistenerUI (void* data) { + NLParams* params = static_cast(data); + params->listener->queueSizeChanged (params->qsize, params->queueEmptied); + delete params; + return 0; +} + +void BatchQueue::notifyListener (bool queueEmptied) { + + if (listener) { + NLParams* params = new NLParams; + params->listener = listener; + params->qsize = fd.size(); + params->queueEmptied = queueEmptied; + g_idle_add (bqnotifylistenerUI, params); + } +} + +void BatchQueue::redrawNeeded (LWButton* button) { + + queue_draw (); +} diff --git a/rtgui/batchqueue.h b/rtgui/batchqueue.h new file mode 100644 index 000000000..73d3de48f --- /dev/null +++ b/rtgui/batchqueue.h @@ -0,0 +1,88 @@ +/* + * 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 "batchqueueentry.h" +#include "../rtengine/rtengine.h" +#include "options.h" +#include "lwbuttonset.h" +#include "thumbbrowserbase.h" + +class BatchQueueListener { + + public: + virtual void queueSizeChanged (int qsize, bool queueEmptied) =0; + virtual bool canStartNext () =0; +}; + +class FileCatalog; +class BatchQueue : public ThumbBrowserBase, + public rtengine::BatchProcessingListener, + public LWButtonListener { + + protected: + int getMaxThumbnailHeight() const; + + BatchQueueEntry* processing; // holds the currently processed image + + Glib::ustring nameTemplate; + + Gtk::ImageMenuItem* cancel; + Gtk::ImageMenuItem* head; + Gtk::ImageMenuItem* tail; + Gtk::MenuItem* selall; + Gtk::Menu* pmenu; + + 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); + void cancelItems (std::vector* items); + void headItems (std::vector* items); + void tailItems (std::vector* items); + void selectAll (); + + void startProcessing (); + + bool hasJobs () { return (!fd.empty()); } + + rtengine::ProcessingJob* imageReady (rtengine::IImage16* img); + void setProgress (double p); + void rightClicked (ThumbBrowserEntryBase* entry); + void buttonPressed (LWButton* button, int actionCode, void* actionData); + void redrawNeeded (LWButton* button); + + void setBatchQueueListener (BatchQueueListener* l) { listener = l; } + + void loadBatchQueue (); + + static Glib::ustring calcAutoFileNameBase (const Glib::ustring& origFileName); + 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..b9e961ad9 --- /dev/null +++ b/rtgui/batchqueueentry.cc @@ -0,0 +1,178 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#include "batchqueueentry.h" +#include "thumbbrowserbase.h" + +#include +#include "guiutils.h" + +BatchQueueEntry::BatchQueueEntry (rtengine::ProcessingJob* pjob, const rtengine::procparams::ProcParams& pparams, Glib::ustring fname, guint8* previmg, int prevw, int prevh, Thumbnail* thm) + : ThumbBrowserEntryBase(fname), + opreview(previmg), origpw(prevw), origph(prevh), + job(pjob), progress(0), outFileName("") { + + thumbnail=thm; + params = pparams; + + #ifndef WIN32 + // The BatchQueueEntryIdleHelper tracks if an entry has been deleted while it was sitting wating for "idle" + bqih = new BatchQueueEntryIdleHelper; + bqih->bqentry = this; + bqih->destroyed = false; + bqih->pending = 0; + #endif + + if (thumbnail) + thumbnail->increaseRef (); +} + +BatchQueueEntry::~BatchQueueEntry () { + + batchQueueEntryUpdater.removeJobs (this); + delete [] opreview; opreview=NULL; + if (thumbnail) + thumbnail->decreaseRef (); + + #ifndef WIN32 + if (bqih->pending) + bqih->destroyed = true; + else + delete bqih; + #endif +} + +void BatchQueueEntry::refreshThumbnailImage () { + + if (!opreview) + return; + + batchQueueEntryUpdater.process (opreview, origpw, origph, preh, this); // this will asynchronously land at this.updateImage +} + +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; +} + +#ifndef WIN32 + +struct BQUpdateParam { + BatchQueueEntryIdleHelper* bqih; + guint8* img; + int w,h; +}; + +int updateImageUIThread (void* data) { + + BQUpdateParam* params = static_cast(data); + + BatchQueueEntryIdleHelper* bqih = params->bqih; + + // 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; +} +#endif + +// Starts a copy of img->preview via GTK thread +void BatchQueueEntry::updateImage (guint8* img, int w, int h) { + // TODO: Check for Linux/Mac +#ifdef WIN32 + // 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 synchrously + { + GThreadLock lock; + + _updateImage(img,w,h); + } +#else + bqih->pending++; + + BQUpdateParam* param = new BQUpdateParam (); + param->bqih = bqih; + param->img = img; + param->w = w; + param->h = h; + g_idle_add (updateImageUIThread, param); +#endif +} + +void BatchQueueEntry::_updateImage (guint8* img, int w, int h) { + + if (preh == h) { + prew = w; + 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..a17d4cb57 --- /dev/null +++ b/rtgui/batchqueueentry.h @@ -0,0 +1,66 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#ifndef _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; + +public: + rtengine::ProcessingJob* job; + rtengine::procparams::ProcParams params; + Glib::ustring savedParamsFile; + double progress; + Glib::ustring outFileName; + SaveFormat saveFormat; + + BatchQueueEntry (rtengine::ProcessingJob* job, const rtengine::procparams::ProcParams& pparams, Glib::ustring fname, guint8* previmg, 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 (); + + // bqentryupdatelistener interface + void updateImage (guint8* img, int w, int h); + 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..04c8720fb --- /dev/null +++ b/rtgui/batchqueuepanel.cc @@ -0,0 +1,264 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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" + + +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); + outdirFolder = Gtk::manage (new MyFileChooserButton (M("PREFERENCES_OUTDIRFOLDER"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); + hb3->pack_start (*outdirFolder); + odvb->pack_start (*hb3, Gtk::PACK_SHRINK, 4); + outdirFolder->set_tooltip_markup (M("PREFERENCES_OUTDIRFOLDERHINT")); + 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); + if (safe_file_test (options.savePathFolder, Glib::FILE_TEST_IS_DIR)) + outdirFolder->set_current_folder (options.savePathFolder); + useTemplate->set_active (options.saveUsePathTemplate); + useFolder->set_active (!options.saveUsePathTemplate); + + // setup signal handlers + outdirTemplate->signal_changed().connect (sigc::mem_fun(*this, &BatchQueuePanel::saveOptions)); + outdirFolder->signal_current_folder_changed().connect (sigc::mem_fun(*this, &BatchQueuePanel::pathFolderChanged)); + 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 (); + batchQueue->loadBatchQueue (); +} + + +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) +{ + updateTab ( qsize); + + if (queueEmptied) { + stopBatchProc (); + fdir->set_sensitive (true); + fformat->set_sensitive (true); + + SoundManager::playSoundAsync(options.sndBatchQueueDone); + } +} + +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 (); +} + +// 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 (); + +} diff --git a/rtgui/batchqueuepanel.h b/rtgui/batchqueuepanel.h new file mode 100644 index 000000000..2f37a3ed2 --- /dev/null +++ b/rtgui/batchqueuepanel.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 _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::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 canStartNext (); + + void startBatchProc (); + void stopBatchProc (); + + void saveOptions (); + void pathFolderChanged (); + void formatChanged (Glib::ustring f); + void updateTab (int qsize); +}; +#endif + diff --git a/rtgui/batchtoolpanelcoord.cc b/rtgui/batchtoolpanelcoord.cc new file mode 100644 index 000000000..4b4457054 --- /dev/null +++ b/rtgui/batchtoolpanelcoord.cc @@ -0,0 +1,397 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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) { + + // 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) { + + toneCurve->setAdjusterBehavior (false, false, false, false, false, false, false, false); + lcurve->setAdjusterBehavior (false, false, false); + whitebalance->setAdjusterBehavior (false, false); + vibrance->setAdjusterBehavior (false, false, false); + vignetting->setAdjusterBehavior (false, false, false, false); + rotate->setAdjusterBehavior (false); + distortion->setAdjusterBehavior (false); + perspective->setAdjusterBehavior (false); + cacorrection->setAdjusterBehavior (false); + sharpening->setAdjusterBehavior (false); + sharpenEdge->setAdjusterBehavior (false, false); + sharpenMicro->setAdjusterBehavior (false, false); + icm->setAdjusterBehavior (false, false); + + chmixer->setAdjusterBehavior (false); + shadowshighlights->setAdjusterBehavior (false, false, false); + dirpyrequalizer->setAdjusterBehavior (false); + dirpyrdenoise->setAdjusterBehavior (false, false); + preprocess->setAdjusterBehavior (false, false); + rawcacorrection->setAdjusterBehavior (false); + rawexposure->setAdjusterBehavior (false, false, false); + } + else { + + 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]); + vignetting->setAdjusterBehavior (options.baBehav[ADDSET_VIGN_AMOUNT], options.baBehav[ADDSET_VIGN_RADIUS], options.baBehav[ADDSET_VIGN_STRENGTH], options.baBehav[ADDSET_VIGN_CENTER]); + rotate->setAdjusterBehavior (options.baBehav[ADDSET_ROTATE_DEGREE]); + distortion->setAdjusterBehavior (options.baBehav[ADDSET_DIST_AMOUNT]); + perspective->setAdjusterBehavior (options.baBehav[ADDSET_PERSPECTIVE]); + 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]); + shadowshighlights->setAdjusterBehavior (options.baBehav[ADDSET_SH_HIGHLIGHTS], options.baBehav[ADDSET_SH_SHADOWS], options.baBehav[ADDSET_SH_LOCALCONTRAST]); + dirpyrequalizer->setAdjusterBehavior (options.baBehav[ADDSET_DIRPYREQ]); + dirpyrdenoise->setAdjusterBehavior (options.baBehav[ADDSET_DIRPYRDN_CHLUM], 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_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_VIBRANCE_PASTELS]) pparams.vibrance.pastels = 0; + if (options.baBehav[ADDSET_VIBRANCE_SATURATED]) pparams.vibrance.saturated = 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_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_DIRPYRDN_CHLUM]) 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) { + + if (!selected.empty()) + selected[0]->getAutoWB (temp, green); +} + +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) { + closeSession (false); + initSession (); + } +} + +/* + * 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..9bf18c94c --- /dev/null +++ b/rtgui/batchtoolpanelcoord.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 __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 ThumbnailListener +{ + protected: + rtengine::procparams::ProcParams pparams; + ParamsEdited pparamsEdited; + std::vector selected; + std::vector selFileNames; + std::vector initialPP; + bool somethingChanged; + 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); + void getCamWB (double& temp, double& green); + + // thumbnaillistener interface + void procParamsChanged (Thumbnail* thm, int whoChangedIt); + + // 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/bqentryupdater.cc b/rtgui/bqentryupdater.cc new file mode 100644 index 000000000..f5463bda3 --- /dev/null +++ b/rtgui/bqentryupdater.cc @@ -0,0 +1,131 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#include "bqentryupdater.h" +#include +#include "guiutils.h" + +BatchQueueEntryUpdater batchQueueEntryUpdater; + +BatchQueueEntryUpdater::BatchQueueEntryUpdater () + : tostop(false), stopped(true), qMutex(NULL) { +} + +void BatchQueueEntryUpdater::process (guint8* oimg, int ow, int oh, int newh, BQEntryUpdateListener* listener) { + if (!qMutex) + qMutex = new Glib::Mutex (); + + 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; + 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; + 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 && 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); + } + } + + 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 currenly running thread and wait till it's finished + gdk_threads_leave(); + tostop = true; + Glib::Thread::self()->yield(); + if (!stopped) thread->join (); + gdk_threads_enter(); + } + + // 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..affc088ce --- /dev/null +++ b/rtgui/bqentryupdater.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 _BQENTRYUPDATER_ +#define _BQENTRYUPDATER_ + +#include +#include "../rtengine/rtengine.h" +#include "thumbnail.h" + +class BQEntryUpdateListener { + + public: + virtual void updateImage (guint8* img, int w, int h) {} +}; + +class BatchQueueEntryUpdater { + + struct Job { + guint8* oimg; + int ow, oh, newh; + BQEntryUpdateListener* listener; + }; + + protected: + bool tostop; + bool stopped; + std::list jqueue; + Glib::Thread* thread; + Glib::Mutex* qMutex; + + public: + BatchQueueEntryUpdater (); + + void process (guint8* oimg, int ow, int oh, int newh, BQEntryUpdateListener* listener); + 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..9b207a160 --- /dev/null +++ b/rtgui/cacheimagedata.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 "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), thumbImgType(0) { +} + +int CacheImageData::load (const Glib::ustring& fname) { + + rtengine::SafeKeyFile keyFile; + + try { + if (!keyFile.load_from_file (fname)) + return 1; + + 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", "Camera")) camera = keyFile.get_string ("ExifInfo", "Camera"); + } + + 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) { + return 1; + } +} + +int CacheImageData::save (const Glib::ustring& fname) { + + rtengine::SafeKeyFile keyFile; + + if (safe_file_test(fname,Glib::FILE_TEST_EXISTS)) keyFile.load_from_file (fname); + + 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", "Camera", camera); + 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) + 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..4c31cba77 --- /dev/null +++ b/rtgui/cacheimagedata.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 _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 camera; + Glib::ustring filetype; + Glib::ustring expcomp; + + // 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); +}; +#endif diff --git a/rtgui/cachemanager.cc b/rtgui/cachemanager.cc new file mode 100644 index 000000000..05cc52d11 --- /dev/null +++ b/rtgui/cachemanager.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 "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 Glib::Mutex smutex_; + Glib::Mutex::Lock lock(smutex_); + if ( instance_ == 0 ) + { + instance_ = new CacheManager(); + } + } + return instance_; +} + +void CacheManager::init () { + + Glib::Mutex::Lock 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 + { + Glib::Mutex::Lock 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) + { + Glib::Mutex::Lock 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) { + + Glib::Mutex::Lock 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) + ".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) + ".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) + ".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) { + + Glib::Mutex::Lock 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) + ".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) { + + Glib::Mutex::Lock 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 () { + + Glib::Mutex::Lock lock(mutex_); + + applyCacheSizeLimitation (); +} + +void CacheManager::clearAll () { + + Glib::Mutex::Lock 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 () { + + Glib::Mutex::Lock lock(mutex_); + + deleteDir ("images"); + deleteDir ("aehistograms"); + deleteDir ("embprofiles"); +} + +void CacheManager::clearProfiles () { + Glib::Mutex::Lock 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) + ".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..aa441706c --- /dev/null +++ b/rtgui/cachemanager.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 _CACHEMANAGER_ +#define _CACHEMANAGER_ + +#include +#include +#include +#include "thumbnail.h" +#include + +class Thumbnail; + +class CacheManager { + + typedef std::pair string_thumb_pair; + typedef std::map string_thumb_map; + + string_thumb_map openEntries; + Glib::ustring baseDir; + Glib::Mutex 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 () { Glib::Mutex::Lock 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..a2483873e --- /dev/null +++ b/rtgui/cacorrection.cc @@ -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 . + */ +#include "cacorrection.h" +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +CACorrection::CACorrection () : Gtk::VBox(), FoldableToolPanel(this) { + + red = Gtk::manage (new Adjuster (M("TP_CACORRECTION_RED"), -0.005, 0.005, 0.0001, 0)); + red->setAdjusterListener (this); + + blue = Gtk::manage (new Adjuster (M("TP_CACORRECTION_BLUE"), -0.005, 0.005, 0.0001, 0)); + 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..8575a7be1 --- /dev/null +++ b/rtgui/chmixer.cc @@ -0,0 +1,185 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#include "chmixer.h" +#include "rtimage.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +extern Glib::ustring argv0; + +ChMixer::ChMixer (): Gtk::VBox(), FoldableToolPanel(this) { + + 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 (imgIcon[0], -200, 200, 1, 100)); + red[1] = Gtk::manage (new Adjuster (imgIcon[1], -200, 200, 1, 0)); + red[2] = Gtk::manage (new Adjuster (imgIcon[2], -200, 200, 1, 0)); + + 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::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 (imgIcon[3], -200, 200, 1, 0)); + green[1] = Gtk::manage (new Adjuster (imgIcon[4], -200, 200, 1, 100)); + green[2] = Gtk::manage (new Adjuster (imgIcon[5], -200, 200, 1, 0)); + + 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::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 (imgIcon[6], -200, 200, 1, 0)); + blue[1] = Gtk::manage (new Adjuster (imgIcon[7], -200, 200, 1, 0)); + blue[2] = Gtk::manage (new Adjuster (imgIcon[8], -200, 200, 1, 100)); + + 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..cce305e3d --- /dev/null +++ b/rtgui/clipboard.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 _CLIPBOARD_ +#define _CLIPBOARD_ + +#include +#include "../rtengine/rtengine.h" +#include "../rtengine/procparams.h" +#include "paramsedited.h" +#include "mydiagonalcurve.h" + +class Clipboard { + + bool _hasIPTC; + rtengine::procparams::IPTCPairs iptc; + rtengine::procparams::PartialProfile partProfile; + DiagonalCurveType hasCurveDataType; + std::vector curve; + + + 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 setCurveData (std::vector& p, DiagonalCurveType type ) { curve = p; hasCurveDataType = type; return; } + const std::vector & getCurveData () { return curve; } + DiagonalCurveType hasCurveData () { return hasCurveDataType; } + + Clipboard (); + ~Clipboard (); + +}; + +extern Clipboard clipboard; + +#endif diff --git a/rtgui/coarsepanel.cc b/rtgui/coarsepanel.cc new file mode 100644 index 000000000..91ebc60d9 --- /dev/null +++ b/rtgui/coarsepanel.cc @@ -0,0 +1,149 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#include "coarsepanel.h" +#include "rtimage.h" + +extern Glib::ustring argv0; + +using namespace rtengine; +using namespace rtengine::procparams; + +CoarsePanel::CoarsePanel () : ToolPanel () { + + degree = 0; + + 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 (); + + if (pedited) { + degree = 0; + hflip->set_active (pedited->coarse.hflip ? pp->coarse.hflip : false); + vflip->set_active (pedited->coarse.vflip ? pp->coarse.vflip : false); + oldhflip = pp->coarse.hflip; + oldvflip = pp->coarse.vflip; + } + else { + degree = pp->coarse.rotate; + hflip->set_active (pp->coarse.hflip); + vflip->set_active (pp->coarse.vflip); + } + enableListener (); +} + +void CoarsePanel::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->coarse.rotate = degree; + + if (pedited) { + pedited->coarse.rotate = degree!=0; + pedited->coarse.hflip = oldhflip != hflip->get_active (); + pedited->coarse.vflip = oldvflip != vflip->get_active (); + pp->coarse.hflip = oldhflip != hflip->get_active (); + pp->coarse.vflip = oldvflip != vflip->get_active (); + } + else { + 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; + if (listener) + listener->panelChanged (EvCTRotate, Glib::ustring::format (degree)); +} + +void CoarsePanel::rotateRight () { + + degree = (degree + 90) % 360; + 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..cfdf74252 --- /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; + + 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/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) { + + 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::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) { + (static_cast(data))->notifyListener (); + return 0; +} + +int refreshSpinsUI (void* data) { + 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 safe 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) { + 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) { + + if (W<0) + W = 0; + if (H<0) + H = 0; + + if (X<0) { + W += X; + X = 0; + } + if (fixr->get_active()) { + double r = getRatio(); + int W2max = (int)round(r*(maxh-Y)); + if (W>W2max) { + X += W - W2max; + W = W2max; + } + H = (int)round(W / r); + } + + 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::cropWidth2Resized (int &X, int &Y, int &W, int &H) { + +// X = x->get_value (); +// Y = y->get_value (); + X = nx; + Y = ny; + + if (W<0) + W = 0; + if (H<0) + H = 0; + + if (W>maxw-X) + W = maxw-X; + + if (fixr->get_active()) { + double r = getRatio(); + int W2max = (int)round(r*(maxh-Y)); + if (W>W2max) + W = W2max; + H = (int)round(W / r); + } + + 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::cropHeight1Resized (int &X, int &Y, int &W, int &H) { + + if (W<0) + W = 0; + if (H<0) + H = 0; + + if (Y<0) { + H += Y; + Y = 0; + } + + if (fixr->get_active()) { + double r = getRatio(); + int H2max = (int)round((maxw-X) / r); + if (H>H2max) { + Y += H - H2max; + H = H2max; + } + W = (int)round(H * r); + } + + 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::cropHeight2Resized (int &X, int &Y, int &W, int &H) { + +// X = x->get_value (); +// Y = y->get_value (); + X = nx; + Y = ny; + + if (W<0) + W = 0; + if (H<0) + H = 0; + int H1max = maxh-Y; + if (H>H1max) + H = H1max; + if (fixr->get_active()) { + double r = getRatio (); + int H2max = (int)round ((maxw-X) / r); + if (H>H2max) + H = H2max; + W = (int)round(H * r); + } + + 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::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..49a4909bd --- /dev/null +++ b/rtgui/crop.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 _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; + int nx, ny, 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 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..c06113c36 --- /dev/null +++ b/rtgui/cropguilistener.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 __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 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..792262216 --- /dev/null +++ b/rtgui/crophandler.cc @@ -0,0 +1,371 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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 (); + 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..d9dd4dd7d --- /dev/null +++ b/rtgui/crophandler.h @@ -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 . + */ +#ifndef __CROPHANDLER__ +#define __CROPHANDLER__ + +#include "../rtengine/rtengine.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; + + Glib::Mutex 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 100644 index 000000000..20dc4fd28 --- /dev/null +++ b/rtgui/cropwindow.cc @@ -0,0 +1,1320 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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 "../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[] = {{" 10%", 0.1, 10}, + {"12.5%", 0.125, 8}, + {"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 14 +#define ZOOM11INDEX 7 + +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%"); + + 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) { + 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 (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==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==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 { + /*Glib::Mutex::Lock 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 && xcropHandler.cropParams.x+CROPRESIZEBORDER && + x1cropHandler.cropParams.y-CROPRESIZEBORDER && + y1cropHandler.cropParams.x+CROPRESIZEBORDER && + x1cropHandler.cropParams.y+cropHandler.cropParams.h-1-CROPRESIZEBORDER && + y1cropHandler.cropParams.y+CROPRESIZEBORDER && + y1cropHandler.cropParams.x-CROPRESIZEBORDER && + x1cropHandler.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 (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==SCropWinResize) + cursorManager.setCursor (iarea->get_window(), CSResizeDiagonal); +} + +void CropWindow::expose (Cairo::RefPtr cr) { + Glib::Mutex::Lock 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; +// PERFORMANCE BOTTLENECK STARTS HERE + //t3.set (); + bool showcs = iarea->indClippedPanel->showClippedShadows(); + bool showch = iarea->indClippedPanel->showClippedHighlights(); + bool showR = iarea->previewModePanel->showR(); + bool showG = iarea->previewModePanel->showG(); + bool showB = iarea->previewModePanel->showB(); + bool showL = iarea->previewModePanel->showL(); + bool showFocusMask = iarea->previewModePanel->showFocusMask(); + // additional flags to control clipping indicators for individual channels and across all channels + bool showclippedAll = (!showR && !showG && !showB && !showL); + bool showclippedR = showR || showL || showclippedAll; + bool showclippedG = showG || showL || showclippedAll; + bool showclippedB = showB || showL || showclippedAll; + + // If ALT was pressed, auto-enable highlight and shadow + // TODO: Add linux/MacOS specific functions for alternative + #ifdef WIN32 + if (GetKeyState(VK_MENU)<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; + + if (showch) { + delta=0; changedHL=false; + + if (currWS[0]>=options.highlightThreshold && showclippedR) { delta += 255-currWS[0]; changedHL=true; } + if (currWS[1]>=options.highlightThreshold && showclippedG) { delta += 255-currWS[1]; changedHL=true; } + if (currWS[2]>=options.highlightThreshold && showclippedB) { delta += 255-currWS[2]; changedHL=true; } + + if (changedHL) { + delta *= HighlightFac; + if (showclippedAll) 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 && showclippedR) { delta += currWS[0]; changedSH=true; } + if (currWS[1]<=options.shadowThreshold && showclippedG) { delta += currWS[1]; changedSH=true; } + if (currWS[2]<=options.shadowThreshold && showclippedB) { delta += currWS[2]; changedSH=true; } + + if (changedSH) { + if (showclippedAll) { + 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; + } + + 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; + } + + changeZoom (cropZoom-1, true, x, y); + fitZoom = false; +} + +void CropWindow::zoom11 () { + + changeZoom (ZOOM11INDEX); + 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; + } + 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 100644 index 000000000..b049f3fd5 --- /dev/null +++ b/rtgui/cropwindow.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 _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 + + // 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..6315bc84c --- /dev/null +++ b/rtgui/cursormanager.cc @@ -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 . + */ +#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); + 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==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..3f2f853f1 --- /dev/null +++ b/rtgui/cursormanager.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 _CURSORMANAGER_ +#define _CURSORMANAGER_ + +#include + +enum CursorShape {CSArrow, CSOpenHand, CSClosedHand, CSMove, CSMoveLeft, CSMoveRight, CSResizeWidth, CSResizeHeight, CSResizeDiagonal, CSSpotWB, CSCropSelect, CSStraighten, CSPlus, CSWait, CSEmpty}; + +class CursorManager { + + protected: + Gdk::Cursor* cResizeWidth; + Gdk::Cursor* cResizeHeight; + Gdk::Cursor* cResizeDiag; + 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..05ba0dd2c --- /dev/null +++ b/rtgui/curveeditor.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. + * + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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; + + // 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..6167fa8ec --- /dev/null +++ b/rtgui/curveeditor.h @@ -0,0 +1,166 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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 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; + + public: + FlatCurveEditor (Glib::ustring text, CurveEditorGroup* ceGroup, CurveEditorSubGroup* ceSubGroup, bool isPeriodic = true); + std::vector getCurve (); +}; + +#endif diff --git a/rtgui/curveeditorgroup.cc b/rtgui/curveeditorgroup.cc new file mode 100644 index 000000000..b03676cbe --- /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)) { + 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..76c5d484d --- /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) = 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..193bc1c80 --- /dev/null +++ b/rtgui/darkframe.cc @@ -0,0 +1,148 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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) +{ + 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..91e405a26 --- /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() {} + // 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..ba09b7dd3 --- /dev/null +++ b/rtgui/defringe.cc @@ -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 . + */ +#include "defringe.h" +#include +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +Defringe::Defringe () : Gtk::VBox(), FoldableToolPanel(this) { + + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); + 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, &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, 25)); + radius->setAdjusterListener (this); + threshold->setAdjusterListener (this); + radius->show(); + threshold->show(); + + pack_start (*radius); + pack_start (*threshold); +} + +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); + } + + 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); + + enableListener (); +} + +void Defringe::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->defringe.radius = radius->getValue (); + pp->defringe.threshold = (int)threshold->getValue (); + pp->defringe.enabled = enabled->get_active(); + + if (pedited) { + pedited->defringe.radius = radius->getEditedState (); + pedited->defringe.threshold = threshold->getEditedState (); + pedited->defringe.enabled = !enabled->get_inconsistent(); + } +} + +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::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..0030cc064 --- /dev/null +++ b/rtgui/defringe.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 _DEFRINGE_H_ +#define _DEFRINGE_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" + +class Defringe : public Gtk::VBox, public AdjusterListener, public FoldableToolPanel { + + protected: + Adjuster* radius; + Adjuster* threshold; + Gtk::CheckButton* enabled; + bool lastEnabled; + sigc::connection enaConn; + bool edges; + + public: + + 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 adjusterChanged (Adjuster* a, double newval); + void enabledChanged (); + +}; + +#endif diff --git a/rtgui/diagonalcurveeditorsubgroup.cc b/rtgui/diagonalcurveeditorsubgroup.cc new file mode 100644 index 000000000..05676d566 --- /dev/null +++ b/rtgui/diagonalcurveeditorsubgroup.cc @@ -0,0 +1,729 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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.setCurveData (curve,DCT_Spline); + break; + case DCT_Parametric: // parametric + // ... do something, first add save/load functions + curve = paramCurve->getPoints (); + clipboard.setCurveData (curve,DCT_Parametric); + break; + case DCT_NURBS: // NURBS + curve = NURBSCurve->getPoints (); + clipboard.setCurveData (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.hasCurveData(); + + if (type == (DiagonalCurveType)parent->displayedCurve->selected) { + curve = clipboard.getCurveData (); + switch (type) { + case DCT_Linear: // linear + break; + 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) { + 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..d4fac0949 --- /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); + 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..3c5a7b972 --- /dev/null +++ b/rtgui/dirbrowser.cc @@ -0,0 +1,365 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#include "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 +extern Glib::ustring argv0; + +DirBrowser::DirBrowser () { + + 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); +#elif defined __APPLE__ + printf("TODO fix dir->monitor_directory () for OSX\n"); +#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)) { + 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) + 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 (); + + + 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); + for (size_t i=0; idirSelected (absDirPath, Glib::build_filename (absDirPath, fileName)); +} + +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; + + gdk_threads_enter(); + updateDir (iter); + gdk_threads_leave(); +} + +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..0da2f8a11 --- /dev/null +++ b/rtgui/dirpyrdenoise.cc @@ -0,0 +1,190 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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) { + + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); + 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, 80)); + chroma = Gtk::manage (new Adjuster (M("TP_DIRPYRDENOISE_CHROMA"), 0, 100, 0.01, 15)); + gamma = Gtk::manage (new Adjuster (M("TP_DIRPYRDENOISE_GAMMA"), 1.0, 3.0, 0.01, 1.7)); + + + luma->setAdjusterListener (this); + Ldetail->setAdjusterListener (this); + chroma->setAdjusterListener (this); + gamma->setAdjusterListener (this); + + luma->show(); + Ldetail->show(); + chroma->show(); + gamma->show(); + + pack_start (*luma); + pack_start (*Ldetail); + pack_start (*chroma); + pack_start (*gamma); + +} + +void DirPyrDenoise::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + if (pedited) { + luma->setEditedState (pedited->dirpyrDenoise.luma ? Edited : UnEdited); + Ldetail->setEditedState (pedited->dirpyrDenoise.Ldetail ? Edited : UnEdited); + chroma->setEditedState (pedited->dirpyrDenoise.chroma ? Edited : UnEdited); + gamma->setEditedState (pedited->dirpyrDenoise.gamma ? Edited : UnEdited); + enabled->set_inconsistent (!pedited->dirpyrDenoise.enabled); + } + + enaConn.block (true); + enabled->set_active (pp->dirpyrDenoise.enabled); + enaConn.block (false); + + lastEnabled = pp->dirpyrDenoise.enabled; + + luma->setValue (pp->dirpyrDenoise.luma); + Ldetail->setValue (pp->dirpyrDenoise.Ldetail); + chroma->setValue (pp->dirpyrDenoise.chroma); + gamma->setValue (pp->dirpyrDenoise.gamma); + + 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.gamma = gamma->getValue (); + pp->dirpyrDenoise.enabled = enabled->get_active(); + + if (pedited) { + pedited->dirpyrDenoise.luma = luma->getEditedState (); + pedited->dirpyrDenoise.Ldetail = Ldetail->getEditedState (); + pedited->dirpyrDenoise.chroma = chroma->getEditedState (); + pedited->dirpyrDenoise.gamma = gamma->getEditedState (); + pedited->dirpyrDenoise.enabled = !enabled->get_inconsistent(); + } +} + +void DirPyrDenoise::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + luma->setDefault (defParams->dirpyrDenoise.luma); + Ldetail->setDefault (defParams->dirpyrDenoise.Ldetail); + chroma->setDefault (defParams->dirpyrDenoise.chroma); + 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); + gamma->setDefaultEditedState (pedited->dirpyrDenoise.gamma ? Edited : UnEdited); + } + else { + luma->setDefaultEditedState (Irrelevant); + Ldetail->setDefaultEditedState (Irrelevant); + chroma->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==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::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + luma->showEditedCB (); + Ldetail->showEditedCB (); + chroma->showEditedCB (); + gamma->showEditedCB (); +} + +void DirPyrDenoise::setAdjusterBehavior (bool chrolumaadd, bool gammaadd) { + + luma->setAddMode(chrolumaadd); + Ldetail->setAddMode(chrolumaadd); + chroma->setAddMode(chrolumaadd); + 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); + gamma->trimValue(pp->dirpyrDenoise.gamma); +} diff --git a/rtgui/dirpyrdenoise.h b/rtgui/dirpyrdenoise.h new file mode 100644 index 000000000..0aad76286 --- /dev/null +++ b/rtgui/dirpyrdenoise.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 _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* gamma; + + Gtk::CheckButton* enabled; + bool lastEnabled; + sigc::connection enaConn; + + 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 setAdjusterBehavior (bool chrolumaadd, 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..7b8bc7e61 --- /dev/null +++ b/rtgui/dirpyrequalizer.cc @@ -0,0 +1,236 @@ +/* + * 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) { + + 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) ); + + 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 < 4; i++) + { + Glib::ustring ss; + ss = Glib::ustring::format(i); + if(i == 0) { + ss += Glib::ustring::compose(" (%1)", M("TP_DIRPYREQUALIZER_LUMAFINEST")); + multiplier[i] = Gtk::manage ( new Adjuster (ss, 0, 4, 0.01, 1.0) ); + } else { + if(i == 3) + 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); + + multiplier[4] = Gtk::manage ( new Adjuster (M("TP_DIRPYREQUALIZER_THRESHOLD"), 0, 1, 0.01, 0.2) ); + multiplier[4]->setAdjusterListener(this); + pack_start(*multiplier[4]); + + 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); + } + } + + 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]); + } + + 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(); + } + + if (pedited) { + + pedited->dirpyrequalizer.enabled = !enabled->get_inconsistent(); + + for(int i = 0; i < 5; i++) { + pedited->dirpyrequalizer.mult[i] = multiplier[i]->getEditedState(); + } + } +} + +void DirPyrEqualizer::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + for (int i = 0; i < 5; i++) { + multiplier[i]->setDefault(defParams->dirpyrequalizer.mult[i]); + } + + if (pedited) { + for (int i = 0; i < 5; i++) { + multiplier[i]->setDefaultEditedState(pedited->dirpyrequalizer.mult[i] ? Edited : UnEdited); + } + } + else { + for (int i = 0; i < 5; i++) { + multiplier[i]->setDefaultEditedState(Irrelevant); + } + } +} + +void DirPyrEqualizer::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + + for (int i = 0; i < 5; i++) { + multiplier[i]->showEditedCB(); + } +} + +void DirPyrEqualizer::adjusterChanged (Adjuster* a, double newval) { + + if (listener && enabled->get_active()) { + std::stringstream ss; + ss << "("; + int i; + for (i = 0; i < 5; i++) { + if (i > 0) { + ss << ", "; + } + ss << static_cast(multiplier[i]->getValue()); + } + ss << ")"; + listener->panelChanged (EvDirPyrEqualizer, ss.str()); + } +} + +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 < 4; i++) { + multiplier[i]->setValue(1.0); + adjusterChanged(multiplier[i], 1.0); + } +} + + +void DirPyrEqualizer::lumacontrastPlusPressed () { + + for (int i = 0; i < 4; i++) { + float inc = 0.05 * (4 - i); + multiplier[i]->setValue(multiplier[i]->getValue() + inc); + adjusterChanged(multiplier[i], multiplier[i]->getValue()); + } +} + + +void DirPyrEqualizer::lumacontrastMinusPressed () { + + for (int i = 0; i < 4; i++) { + float inc = -0.05 * (4 - i); + multiplier[i]->setValue(multiplier[i]->getValue() + inc); + adjusterChanged(multiplier[i], multiplier[i]->getValue()); + } +} + +void DirPyrEqualizer::setAdjusterBehavior (bool multiplieradd) { + + for (int i=0; i<5; i++) + multiplier[i]->setAddMode(multiplieradd); +} + +void DirPyrEqualizer::trimValues (rtengine::procparams::ProcParams* pp) { + + for (int i=0; i<5; i++) + multiplier[i]->trimValue(pp->dirpyrequalizer.mult[i]); +} diff --git a/rtgui/dirpyrequalizer.h b/rtgui/dirpyrequalizer.h new file mode 100644 index 000000000..78a0e660c --- /dev/null +++ b/rtgui/dirpyrequalizer.h @@ -0,0 +1,61 @@ +/* + * 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]; + + 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); + 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..6dd09a3a6 --- /dev/null +++ b/rtgui/dirselectionlistener.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 _DIRSELECTIONLISTENER_ +#define _DIRSELECTIONLISTENER_ + +#include + +class DirSelectionListener { + + public: + 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..a4e87cd07 --- /dev/null +++ b/rtgui/distortion.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 "distortion.h" +#include +#include "rtimage.h" + +extern Glib::ustring argv0; + +using namespace rtengine; +using namespace rtengine::procparams; + +Distortion::Distortion (): Gtk::VBox(), FoldableToolPanel(this) { + + 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); + + distor = Gtk::manage (new Adjuster (M("TP_DISTORTION_AMOUNT"), -0.5, 0.5, 0.001, 0)); + 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..bfccf3e65 --- /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, SCropSelecting, SRotateSelecting, SCropWinMove, SCropFrameMove, SCropImgMove, SCropWinResize, SObservedMove}; +enum CursorArea {CropWinButtons, CropToolBar, CropImage, CropBorder, CropTop, CropBottom, CropLeft, CropRight, CropInside, CropResize, CropObserved}; + +#endif diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc new file mode 100644 index 000000000..eaa497040 --- /dev/null +++ b/rtgui/editorpanel.cc @@ -0,0 +1,1506 @@ +/* + * 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" + +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); + + 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) ); + 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::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(); + //saveAsDialog->setInitialFileName (removeExtension (Glib::path_get_basename (fname))); + 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 (Glib::path_get_basename (fname) + paramFileExtension); + + 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 ) +{ + 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 + 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 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(), + 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", + Glib::path_get_dirname(openThm->getFileName()) + G_DIR_SEPARATOR_S, + Glib::path_get_basename(openThm->getFileName())); + + infoString = Glib::ustring::compose ("%1\n%2\n%3",infoString1, infoString2, infoString3); + } + 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; + + + // 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; + } + + 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_1: + iareapanel->imageArea->zoomPanel->zoom11Clicked(); + return true; + + case GDK_8: //background color of the preview 0 + iareapanel->imageArea->previewModePanel->togglebackColor0(); + return true; + case GDK_9: //background color of the preview 1 + iareapanel->imageArea->previewModePanel->togglebackColor1(); + return true; + case GDK_0: //background color of the preview 2 + iareapanel->imageArea->previewModePanel->togglebackColor2(); + return true; + + 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; + } + } + 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_q: + 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(tpc->getToolBar()->handleShortcutKey(event)) + return true; + if(tpc->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 prevh = options.maxThumbnailHeight; + int prevw = prevh; + guint8* prev = NULL;//(guint8*) previewHandler->getImagePreview (prevw, prevh); + double tmpscale; + rtengine::IImage8* img = openThm->processThumbImage (pparams, options.maxThumbnailHeight, tmpscale); + if (img) { + prevw = img->getWidth (); + prevh = img->getHeight (); + prev = new guint8 [prevw*prevh*3]; + memcpy (prev, img->getData (), prevw*prevh*3); + img->free(); + } + return new BatchQueueEntry (job, pparams, openThm->getFileName(), prev, 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); + + 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; + + 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 (); + 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); +} + +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); + } +#else + cmdLine = Glib::ustring("gimp-remote ") + Glib::ustring(" \"") + filename + Glib::ustring("\""); + success = safe_spawn_command_line_async (cmdLine); +#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("gimp \"") + filename + Glib::ustring("\""); + success = safe_spawn_command_line_async (cmdLine); +#else + cmdLine = Glib::ustring("gimp \"") + filename + Glib::ustring("\""); + success = safe_spawn_command_line_async (cmdLine); +#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); +#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 + filename; + #else + cmdLine = Glib::ustring("\"") + options.customEditorProg + Glib::ustring("\" \"") + filename + Glib::ustring("\""); + #endif + success = safe_spawn_command_line_async (cmdLine); +#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 & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw) { + + if (histogramPanel) histogramPanel->histogramChanged (histRed, histGreen, histBlue, histLuma, histRedRaw, histGreenRaw, histBlueRaw); + tpc->updateCurveBackgroundHistogram (histToneCurve, histLCurve, 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..46d8dc557 --- /dev/null +++ b/rtgui/editorpanel.h @@ -0,0 +1,198 @@ +/* + * 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; + + 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 safed seperately + + 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; } + + // 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 & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw); + + // 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 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..f97960c7b --- /dev/null +++ b/rtgui/editwindow.cc @@ -0,0 +1,224 @@ +/* +* 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" + +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 Glib::Mutex smutex_; + Glib::Mutex::Lock 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..20c9c510a --- /dev/null +++ b/rtgui/epd.cc @@ -0,0 +1,163 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#include "epd.h" +#include +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +EdgePreservingDecompositionUI::EdgePreservingDecompositionUI () : Gtk::VBox(), FoldableToolPanel(this){ + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); + 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, &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..fce35b62b --- /dev/null +++ b/rtgui/exifpanel.cc @@ -0,0 +1,559 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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; +extern Glib::ustring argv0; + +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(), "?", SYSTEM, false); + else + addTag (exifTreeModel->children(), defTags[i]->nameToString(), defTags[i]->valueToString(), 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, int 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==WRITE) + row[exifColumns.icon] = keepicon; + else if (action==DONTWRITE) + row[exifColumns.icon] = delicon; + + if (editable) { + row[exifColumns.field] = Glib::ustring("") + field + ""; + row[exifColumns.value] = Glib::ustring("") + value + ""; + } + else if (action==SYSTEM) { + row[exifColumns.field] = Glib::ustring("") + field + ""; + row[exifColumns.value] = Glib::ustring("") + value + ""; + } + else { + row[exifColumns.field] = field; + row[exifColumns.value] = 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==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 : 0, t->getAttrib() && t->getAttrib()->editable); + addDirectory (t->getDirectory(j), ch); + } + else + addTag (root, t->nameToString (), t->valueToString (), t->getAttrib() ? (t->getOwnMemory()?t->getAttrib()->action:SYSTEM) : 0, 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)==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) != 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) != 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)!=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)==100) + 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)!=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)==100) { + 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, 100); + 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)!=SYSTEM) + iter->set_value (exifColumns.icon, iter->get_value (exifColumns.edited) ? editicon : keepicon); + else if (value=="#delete" && iter->get_value (exifColumns.action)!=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) == WRITE && iter->get_value (exifColumns.icon) == delicon) + changeList[ prefix+iter->get_value (exifColumns.field_nopango) ] = "#delete"; + else if (iter->get_value (exifColumns.action) == 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..5dbc3676b --- /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; // = 0: dont write to output, =1: write to output, =2: chagned by RT (not editable/deletable), =3: new addition + 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, int 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..4e060b97a --- /dev/null +++ b/rtgui/exportpanel.cc @@ -0,0 +1,414 @@ +/* + * 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_alignment(Gtk::ALIGN_LEFT); + pack_start(*labExportTitle, Gtk::PACK_SHRINK, 4); + + Gtk::Label* labInstructions = Gtk::manage ( new Gtk::Label (M("EXPORT_INSTRUCTIONS")) ); + labInstructions->set_use_markup (true); + labInstructions->set_line_wrap (true); + labInstructions->set_alignment(Gtk::ALIGN_LEFT); + Gtk::HBox* hbInstructions = Gtk::manage (new Gtk::HBox ()); + hbInstructions->pack_start(*labInstructions, Gtk::PACK_SHRINK, 4); + pack_start(*hbInstructions, 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"))); + + 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_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_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_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_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_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_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_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..f7318967a --- /dev/null +++ b/rtgui/exportpanel.h @@ -0,0 +1,114 @@ +/* + * 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_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_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..e8802a0ec --- /dev/null +++ b/rtgui/extprog.cc @@ -0,0 +1,169 @@ +/* +* 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 () { + Glib::Mutex::Lock 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", "Kolor\\Autopano Giga 2.%1\\AutopanoGiga_x64.exe", "Kolor\\Autopano Giga 2.%1\\AutopanoGiga.exe", 15, true, true)) + SearchProg("Autopano Pro", "Kolor\\Autopano Pro 2.%1\\AutopanoPro_x64.exe", "Kolor\\Autopano Pro 2.%1\\AutopanoPro.exe", 15, 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>1;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..c5586c592 --- /dev/null +++ b/rtgui/extprog.h @@ -0,0 +1,58 @@ +/* +* 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 + +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 { + Glib::Mutex 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 100644 index 000000000..733a0c88e --- /dev/null +++ b/rtgui/filebrowser.cc @@ -0,0 +1,1164 @@ +/* + * 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 "profilestore.h" +#include "procparamchangers.h" +#include "batchqueue.h" +#include "../rtengine/dfmanager.h" +#include "../rtengine/ffmanager.h" +#include "rtimage.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; + + 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++; + } + } + for (int i=1; i<=5; i++){//set color label images + 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 + * *********************/ +#ifdef WIN32 + 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_Q, 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)); +} + +FileBrowser::~FileBrowser () +{ + delete pmenu; + delete[] amiExtProg; +} + +void FileBrowser::rightClicked (ThumbBrowserEntryBase* entry) { + + 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()); + + // submenu applmenu + int p = 0; + Gtk::Menu* applmenu = Gtk::manage (new Gtk::Menu ()); + std::vector profnames = profileStore.getProfileNames (); + for (size_t i=0; iattach (*mi, 0, 1, p, p+1); p++; + mi->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::applyMenuItemActivated), profnames[i])); + mi->show (); + } + applyprof->set_submenu (*applmenu); + + // submenu applpartmenu + p = 0; + Gtk::Menu* applpartmenu = Gtk::manage (new Gtk::Menu ()); + //std::vector profnames = profileStore.getProfileNames (); // this is already created for submenu applmenu above + for (size_t i=0; iattach (*mi, 0, 1, p, p+1); p++; + mi->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::applyPartialMenuItemActivated), profnames[i])); + mi->show (); + } + applypartprof->set_submenu (*applpartmenu); + + // submenuDF + 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) { + + 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 (getCurrentThumbSize()); + + // find place in abc order + { + // TODO: Check for Linux + #ifdef WIN32 + Glib::RWLock::WriterLock 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) { + // TODO: Check for Linux + #ifdef WIN32 + Glib::RWLock::WriterLock 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); + + #ifdef WIN32 + l.release(); + #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; + + { + // TODO: Check for Linux + #ifdef WIN32 + Glib::RWLock::WriterLock l(entryRW); + #endif + + selected.clear (); + notifySelectionListener (); + + // The listener merges parameters with old values, so delete afterwards + for (size_t i=0; i mselected; + 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; + { + // TODO: Check for Linux + #ifdef WIN32 + Glib::RWLock::ReaderLock 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){ + 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); + } + }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 ){ + 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); + } + } + } + }else if( m==thisIsDF){ + if( !options.rtSettings.darkFramesPath.empty() && 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 if (m==autoFF){ + 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); + } + } + 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 ){ + 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); + } + } + } + } + else if( m==thisIsFF){ + if( !options.rtSettings.flatFieldsPath.empty() && 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 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) { + 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); + } + } 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 (selected.size()==1) + clipboard.setProcParams ((static_cast(selected[0]))->thumbnail->getProcParams()); +} + +void FileBrowser::pasteProfile () { + + if (clipboard.hasProcParams()) { + std::vector mselected; + for (unsigned int i=0; i(selected[i])); + + if (!tbl || mselected.empty()) + return; + + for (unsigned int i=0; ithumbnail->setProcParams (*pastedPartProf.pparams, pastedPartProf.pedited, FILEBROWSER); + pastedPartProf.deleteInstance(); + } + + queue_draw (); + } +} + +void FileBrowser::partPasteProfile () { + + if (clipboard.hasProcParams()) { + + std::vector mselected; + for (unsigned int i=0; i(selected[i])); + + if (!tbl || mselected.empty()) + return; + + int i = partialPasteDlg.run (); + if (i == Gtk::RESPONSE_OK) { + + 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(); + } + + queue_draw (); + } + partialPasteDlg.hide (); + } +} + +void FileBrowser::openDefaultViewer (int destination) { + bool success=true; + 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) { + + if ((event->keyval==GDK_C || event->keyval==GDK_c) && event->state & GDK_CONTROL_MASK) { + copyProfile (); + return true; + } + else if ((event->keyval==GDK_V || event->keyval==GDK_v) && event->state & GDK_CONTROL_MASK && !(event->state & GDK_SHIFT_MASK)) { + pasteProfile (); + return true; + } + else if ((event->keyval==GDK_V || event->keyval==GDK_v) && event->state & GDK_CONTROL_MASK && event->state & GDK_SHIFT_MASK) { + partPasteProfile (); + return true; + } + else if (event->keyval==GDK_Delete && !(event->state & GDK_SHIFT_MASK)) { + menuItemActivated (trash); + return true; + } + else if (event->keyval==GDK_Delete && event->state & GDK_SHIFT_MASK) { + menuItemActivated (untrash); + return true; + } + else if ((event->keyval==GDK_Q || event->keyval==GDK_q) && event->state & GDK_CONTROL_MASK) { + menuItemActivated (develop); + return true; + } + else if ((event->keyval==GDK_A || event->keyval==GDK_a) && event->state & GDK_CONTROL_MASK) { + menuItemActivated (selall); + return true; + } + else if (event->keyval==GDK_F2 && !(event->state & GDK_CONTROL_MASK)) { + menuItemActivated (rename); + 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; + } + + return false; +} + +void FileBrowser::applyMenuItemActivated (Glib::ustring ppname) { + + rtengine::procparams::PartialProfile* partProfile = profileStore.getProfile (ppname); + if (partProfile->pparams && !selected.empty()) { + for (size_t i=0; i(selected[i]))->thumbnail->setProcParams (*partProfile->pparams, partProfile->pedited, FILEBROWSER); + queue_draw (); + } +} + +void FileBrowser::applyPartialMenuItemActivated (Glib::ustring ppname) { + + if (!tbl || selected.empty()) + return; + + rtengine::procparams::PartialProfile* srcProfiles = profileStore.getProfile (ppname); + + if (srcProfiles->pparams) { + if (partialPasteDlg.run()==Gtk::RESPONSE_OK) { + + 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(); + } + 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; + { + // TODO: Check for Linux + #ifdef WIN32 + Glib::RWLock::ReaderLock l(entryRW); // Don't make this a writer lock! + #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; + + if (!cfs->exifValid) + return (!filter.exifFilter.filterCamera || filter.exifFilter.cameras.count(cfs->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(cfs->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); // this can execute customprofilebuilder to generate param file + + // 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) { + + for (size_t i=0; ithumbnail->createProcParamsForUpdate(false, false); // this can execute customprofilebuilder to generate param file + + // 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); +} + +void FileBrowser::colorlabelRequested (std::vector tbe, int colorlabel) { + + for (size_t i=0; ithumbnail->createProcParamsForUpdate(false, false); // this can execute customprofilebuilder to generate param file + + // 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); +} + +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); + } +} + +void FileBrowser::openNextImage () { + // TODO: Check for Linux + #ifdef WIN32 + Glib::RWLock::ReaderLock l(entryRW); + #endif + + if (!fd.empty()) { + for (size_t i=fd.size()-1; i>0; i--) + if (editedFiles.find (fd[i]->filename)!=editedFiles.end()) + if (i entries; + entries.push_back ((static_cast(fd[i+1]))->thumbnail); + tbl->openRequested (entries); + return; + } + if (tbl) { + std::vector entries; + entries.push_back ((static_cast(fd[0]))->thumbnail); + tbl->openRequested (entries); + } + } +} + +void FileBrowser::openPrevImage () { + // TODO: Check for Linux + #ifdef WIN32 + Glib::RWLock::ReaderLock l(entryRW); + #endif + + if (!fd.empty()) { + for (size_t i=0; ifilename)!=editedFiles.end()) + if (i>0 && tbl) { + std::vector entries; + entries.push_back ((static_cast(fd[i-1]))->thumbnail); + tbl->openRequested (entries); + return; + } + if (tbl) { + std::vector entries; + entries.push_back ((static_cast(fd[fd.size()-1]))->thumbnail); + tbl->openRequested (entries); + } + } +} + +int refreshThumbImagesUI (void* data) { + (static_cast(data))->_thumbRearrangementNeeded (); + return 0; +} + +void FileBrowser::_thumbRearrangementNeeded () { + refreshThumbImages (); // arrangeFiles is NOT enough +} + +void FileBrowser::thumbRearrangementNeeded () { + g_idle_add (refreshThumbImagesUI, this); +} + +void FileBrowser::selectionChanged () { + + notifySelectionListener (); +} + +void FileBrowser::notifySelectionListener () { + + if (tbl) { + std::vector thm; + for (size_t i=0; i(selected[i]))->thumbnail); + tbl->selectionChanged (thm); + } +} + +void FileBrowser::redrawNeeded (LWButton* button) { + + 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); +} diff --git a/rtgui/filebrowser.h b/rtgui/filebrowser.h new file mode 100644 index 000000000..529b1f4a6 --- /dev/null +++ b/rtgui/filebrowser.h @@ -0,0 +1,172 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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 "partialpastedlg.h" +#include "exportpanel.h" +#include "extprog.h" + +class FileBrowser; +class FileBrowserEntry; +class FileBrowserListener { + + public: + 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{ + + 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; + + Glib::RefPtr pmaccelgroup; + + 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 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 setFileBrowserListener (FileBrowserListener* l) { tbl = l; } + + void menuItemActivated (Gtk::MenuItem* m); + void applyMenuItemActivated (Glib::ustring ppname); + void applyPartialMenuItemActivated (Glib::ustring ppname); + + 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 openNextImage (); + void openPrevImage (); + void copyProfile (); + void pasteProfile (); + void partPasteProfile (); + + void openDefaultViewer (int destination); + + void thumbRearrangementNeeded (); + void _thumbRearrangementNeeded (); + + void selectionChanged (); + + void setExportPanel (ExportPanel* expanel); + // exportpanel interface + void exportRequested(); + + type_trash_changed trash_changed(); +}; + +#endif diff --git a/rtgui/filebrowserentry.cc b/rtgui/filebrowserentry.cc new file mode 100644 index 000000000..c6058e25c --- /dev/null +++ b/rtgui/filebrowserentry.cc @@ -0,0 +1,611 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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 "../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==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 (updateImageUI, param); +} + +void FileBrowserEntry::_updateImage (rtengine::IImage8* img, double s, rtengine::procparams::CropParams cropParams) { + Glib::RWLock::WriterLock l(lockRW); + + redrawRequests--; + scale = s; + this->cropParams = cropParams; + + bool newLandscape = img->getWidth() > img->getHeight(); + bool rotated=false; + + if (preh == img->getHeight ()) { + prew = img->getWidth (); + + // 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==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); + + 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 (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); + iatlistener->getToolBar()->setTool (TMHand); + } + else if (cropgl && (state==SCropSelecting || state==SResizeH1 || state==SResizeH2 || state==SResizeW1 || state==SResizeW2 || state==SCropMove)) { + cropgl->cropManipReady (); + cropgl = NULL; + iatlistener->cropSelectionReady (); + 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 && ycropParams.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()->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 (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); +} + +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..224ddc5c4 --- /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 (); + + std::vector > getIconsOnImageArea (); + 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 + + bool motionNotify (int x, int y); + bool pressNotify (int button, int type, int bstate, int x, int y); + 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..1231a274e --- /dev/null +++ b/rtgui/filecatalog.cc @@ -0,0 +1,1780 @@ +/* + * 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 + +extern Glib::ustring argv0; + +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 + + //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 (); + + 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!="") + 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 (); + filepanel->loadingThumbs(M("PROGRESSBAR_LOADINGTHUMBS"),0); + +#ifdef WIN32 + wdMonitor = new WinDirMonitor (selectedDirectory, this); +#elif defined __APPLE__ + printf("TODO fix dir->monitor_directory () for OSX\n"); +#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) { + 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) { + GThreadLock lock; + previewReadyUI (dir_id,fdn); +} + +// Called WITHIN gtk thread +void FileCatalog::previewReadyUI (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(); + 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->camera); + dirEFS.lenses.insert (cfs->lens); + dirEFS.expcomp.insert (cfs->expcomp); + previewsLoaded++; + + g_idle_add (refreshProgressBarUI, this); +} + +int prevfinished (void* data) { + GThreadLock lock; + (static_cast(data))->previewsFinishedUI (); + return 0; +} + +// Called within GTK UI thread +void FileCatalog::previewsFinishedUI () { + + redrawAll (); + previewsToLoad = 0; + + if (filterPanel) { + filterPanel->set_sensitive (true); + if ( !hasValidCurrentEFS ){ + 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); +} + +void FileCatalog::previewsFinished (int dir_id) { + + if ( dir_id != selectedDirectoryId ) + { + return; + } + + if (!hasValidCurrentEFS) + 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); +} + +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; + + #pragma omp parallel for ordered + for (size_t i=0; ithumbnail->getProcParams(); + + // if fast mode is selected, override (disable) prams + // 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_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 (tbe[i]->filename, tbe[i]->thumbnail->getType()==FT_Raw, params); + double tmpscale; + rtengine::IImage8* img = tbe[i]->thumbnail->processThumbImage (params, BatchQueue::calcMaxThumbnailHeight(), tmpscale); + + int pw, ph; + guint8* prev=NULL; + + if (img) { + pw = img->getWidth (); + ph = img->getHeight (); + prev = new guint8 [pw*ph*3]; + memcpy (prev, img->getData (), pw*ph*3); + img->free(); + + } else { + tbe[i]->thumbnail->getThumbnailSize (pw, ph); + } + + // processThumbImage is the processing intensive part, but adding to queue must be ordered + #pragma omp ordered + { + entries.push_back(new BatchQueueEntry (pjob, params, tbe[i]->filename, prev, pw, ph, tbe[i]->thumbnail)); + } + } + + 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=="") + 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; + + 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) + 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=="") + 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())) { + if (!internal) + gdk_threads_enter(); + + if (event_type == Gio::FILE_MONITOR_EVENT_CREATED || event_type == Gio::FILE_MONITOR_EVENT_DELETED || event_type == Gio::FILE_MONITOR_EVENT_CHANGED) + reparseDirectory (); + + if (!internal) + gdk_threads_leave(); + } +} + +#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()); + previewReadyUI (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); +} + +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); + } +} +void FileCatalog::buttonQueryClearPressed () { + Query->set_text(""); + FileCatalog::executeQuery (); +} + +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){ + switch (event->keyval) + { + case GDK_Escape: + // Clear Query if the Escape character is pressed within it + FileCatalog::buttonQueryClearPressed (); + return true; + } +} + +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!=""){ + 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); +} + +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); +} + +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; + + 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 (!alt) { + switch(event->keyval) { + case GDK_grave: + categoryButtonToggled(bUnRanked,false); + return true; + case GDK_1: + categoryButtonToggled(bRank[0],false); + return true; + case GDK_2: + categoryButtonToggled(bRank[1],false); + return true; + case GDK_3: + categoryButtonToggled(bRank[2],false); + return true; + case GDK_4: + categoryButtonToggled(bRank[3],false); + return true; + case GDK_5: + categoryButtonToggled(bRank[4],false); + return true; + case GDK_6: + categoryButtonToggled(bEdited[0],false); + return true; + case GDK_7: + categoryButtonToggled(bEdited[1],false); + return true; + + case GDK_Return: + case GDK_KP_Enter: + FileCatalog::buttonBrowsePathPressed (); + return true; + } + } + + if (alt) { + switch(event->keyval) { + case GDK_grave: + categoryButtonToggled(bUnCLabeled,false); + return true; + case GDK_1: + categoryButtonToggled(bCLabel[0],false); + return true; + case GDK_2: + categoryButtonToggled(bCLabel[1],false); + return true; + case GDK_3: + categoryButtonToggled(bCLabel[2],false); + return true; + case GDK_4: + categoryButtonToggled(bCLabel[3],false); + return true; + case GDK_5: + categoryButtonToggled(bCLabel[4],false); + return true; + case GDK_6: + categoryButtonToggled(bRecentlySaved[0],false); + return true; + case GDK_7: + categoryButtonToggled(bRecentlySaved[1],false); + return true; + } + } + + 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) { + 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; + } + } + else { // with Ctrl + switch (event->keyval) { + case GDK_o: + if (!alt){ + BrowsePath->select_region(0, BrowsePath->get_text_length()); + BrowsePath->grab_focus(); + return true; + } + case GDK_f: + if (!alt){ + Query->select_region(0, Query->get_text_length()); + Query->grab_focus(); + return true; + } + } + } + + return false; +} diff --git a/rtgui/filecatalog.h b/rtgui/filecatalog.h new file mode 100644 index 000000000..b53fb4324 --- /dev/null +++ b/rtgui/filecatalog.h @@ -0,0 +1,252 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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" + + +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 + + 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; + + 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 previewReadyUI (int dir_id, FileBrowserEntry* fdn); + 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 (); + 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(); } + + 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..34041a40d --- /dev/null +++ b/rtgui/filepanel.cc @@ -0,0 +1,275 @@ + +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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); + 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); + 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); + + //------------------ + + 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 () { + + 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 (Glib::get_home_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 (Glib::get_home_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 = Gtk::manage (new EditorPanel ()); + parent->addEditorPanel (epanel,Glib::path_get_basename (thm->getFileName())); + epanel->open(thm, pc->returnValue() ); + } else { + 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; + + 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()->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) +{ + 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..269bdd836 --- /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 ("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_POPUPUNRANK"))); + 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_POPUPCOLORLABEL"))); + + buttons[2]->setToolTip (M("FILEBROWSER_POPUPRANK1")); + buttons[3]->setToolTip (M("FILEBROWSER_POPUPRANK2")); + buttons[4]->setToolTip (M("FILEBROWSER_POPUPRANK3")); + buttons[5]->setToolTip (M("FILEBROWSER_POPUPRANK4")); + buttons[6]->setToolTip (M("FILEBROWSER_POPUPRANK5")); +} + +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..f807d31d8 --- /dev/null +++ b/rtgui/filterpanel.cc @@ -0,0 +1,329 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#include "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; +} + +void FilterPanel::valueChanged () { + + if (listener) + listener->exifFilterChanged (); +} diff --git a/rtgui/filterpanel.h b/rtgui/filterpanel.h new file mode 100644 index 000000000..4f3c86a78 --- /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 (); +}; + +#endif diff --git a/rtgui/flatcurveeditorsubgroup.cc b/rtgui/flatcurveeditorsubgroup.cc new file mode 100644 index 000000000..b262d29e4 --- /dev/null +++ b/rtgui/flatcurveeditorsubgroup.cc @@ -0,0 +1,336 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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 "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); + 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 (*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) ); + saveCPoints->set_tooltip_text (M("CURVEEDITOR_TOOLTIPSAVE")); + loadCPoints->set_tooltip_text (M("CURVEEDITOR_TOOLTIPLOAD")); + + 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 (); + } + } + } +} + +/* + * 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) { + switch ((FlatCurveType) cType) { + case (FCT_MinMaxCPoints) : // = Control cage + CPointsCurve->reset (); + 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..630f4cd49 --- /dev/null +++ b/rtgui/flatcurveeditorsubgroup.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 _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; + +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 (); + bool curveReset (int cType); + void removeEditor (); + const std::vector getCurveFromGUI (int type); +}; + +#endif diff --git a/rtgui/flatfield.cc b/rtgui/flatfield.cc new file mode 100644 index 000000000..7e9e2ff43 --- /dev/null +++ b/rtgui/flatfield.cc @@ -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 . + */ +#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) +{ + 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) ); +} + +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")); + +} diff --git a/rtgui/flatfield.h b/rtgui/flatfield.h new file mode 100644 index 000000000..de2f87823 --- /dev/null +++ b/rtgui/flatfield.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 _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() {} + // 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; + +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 setFFProvider (FFProvider* p) { ffp = p; }; +}; + +#endif diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc new file mode 100644 index 000000000..1b105267e --- /dev/null +++ b/rtgui/guiutils.cc @@ -0,0 +1,585 @@ +/* + * 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; + +bool removeIfThere (Gtk::Container* cont, Gtk::Widget* w, bool increference) { + + Glib::ListHandle 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 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(true); + 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..392689c0c --- /dev/null +++ b/rtgui/guiutils.h @@ -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 . + */ +#ifndef __GUI_UTILS_ +#define __GUI_UTILS_ + +#include +#include "../rtengine/rtengine.h" + +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 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 +}; + +/** + * @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..ec092ac04 --- /dev/null +++ b/rtgui/histogrampanel.cc @@ -0,0 +1,788 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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" + +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"); + 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"); + 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 ()); + 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); + 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); + 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")); + 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); + 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); + 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 ); + 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 (*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 rawImage; + delete fullImage; + delete barImage; + + delete redImage_g; + delete greenImage_g; + delete blueImage_g; + delete valueImage_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::raw_toggled () { + if (showRAW->get_active()) { + showRAW->set_image(*rawImage); + showValue->set_sensitive(false); + } + else { + showRAW->set_image(*rawImage_g); + showValue->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()); + histogramArea->queue_draw (); + + histogramRGBArea->updateOptions (showRed->get_active(), showGreen->get_active(), showBlue->get_active(), showValue->get_active(), showRAW->get_active(), showBAR->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 () : + frozen(false), valid(false), needRed(true), needGreen(true), needBlue(true), needLuma(true), rawMode(false), showMode(options.histogramBar), barDisplayed(options.histogramBar) { + + 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; + } + + 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(); + } + } +} + +int histrgbupdate (void* data) { + + gdk_threads_enter (); + + HistogramRGBAreaIdleHelper* harih = static_cast(data); + + if (harih->destroyed) { + if (harih->pending == 1) + delete harih; + else + harih->pending--; + gdk_threads_leave (); + return 0; + } + + harih->harea->renderRGBMarks(-1,-1,-1); + harih->harea->queue_draw (); + + harih->pending--; + gdk_threads_leave (); + + 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) { + + needRed = r; + needGreen = g; + needBlue = b; + needLuma = l; + rawMode = raw; + showMode = bar; + + // 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) : + valid(false), fullMode(options.histogramFullMode), myFullModeListener(fml), oldwidth(-1), needLuma(true), needRed(true), needGreen(true), needBlue(true), rawMode(false) { + + lhist(256); + rhist(256); + ghist(256); + bhist(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) { + + needRed = r; + needGreen = g; + needBlue = b; + needLuma = l; + rawMode = raw; + fullMode = !full; + + 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) { + + if (histRed) { + lhist=histLuma; + rhist=histRed; ghist=histGreen; bhist=histBlue; + rhistRaw=histRedRaw; ghistRaw=histGreenRaw; bhistRaw=histBlueRaw; + + valid = true; + } + else + valid = false; + + haih->pending++; + 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 (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) || (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 (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..0ae4c481e --- /dev/null +++ b/rtgui/histogrampanel.h @@ -0,0 +1,219 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#ifndef _HISTOGRAMPANEL_ +#define _HISTOGRAMPANEL_ + + +#include +#include +#include "../rtengine/LUT.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; + + 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); + + 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; + LUTu lhistRaw, rhistRaw, ghistRaw, bhistRaw; + + bool valid; + bool fullMode; + FullModeListener *myFullModeListener; + int oldwidth, oldheight; + + bool needLuma, needRed, needGreen, needBlue, rawMode; + + 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); + void updateOptions (bool r, bool g, bool b, bool l, bool raw, bool full); + 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::Image *redImage; + Gtk::Image *greenImage; + Gtk::Image *blueImage; + Gtk::Image *valueImage; + Gtk::Image *rawImage; + Gtk::Image *fullImage; + Gtk::Image *barImage; + + 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; + + + sigc::connection rconn; + void setHistInvalid (); + + public: + + HistogramPanel (); + ~HistogramPanel (); + + void histogramChanged (LUTu &histRed, LUTu &histGreen, LUTu &histBlue, LUTu &histLuma, LUTu &histRedRaw, LUTu &histGreenRaw, LUTu &histBlueRaw) { + histogramArea->update (histRed, histGreen, histBlue, histLuma, histRedRaw, histGreenRaw, histBlueRaw); + } + // 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 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..e9212c3e6 --- /dev/null +++ b/rtgui/history.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 "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); + + pack_start (*histFrame); + + 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"))); + 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_SHRINK, 4); + bmBox->pack_end (*ahbox, Gtk::PACK_SHRINK, 4); + + if (bookmarkSupport) + pack_end (*bmFrame, Gtk::PACK_SHRINK, 4); + + 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..1eda0fadd --- /dev/null +++ b/rtgui/history.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 _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::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/hlrec.cc b/rtgui/hlrec.cc new file mode 100644 index 000000000..8141261dc --- /dev/null +++ b/rtgui/hlrec.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 "hlrec.h" +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +HLRecovery::HLRecovery () : Gtk::VBox(), FoldableToolPanel(this) { + + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLE"))); + enabled->set_active (false); + pack_start (*enabled); + + 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); + Gtk::HBox* hb = Gtk::manage (new Gtk::HBox ()); + Gtk::Label* lab = Gtk::manage (new Gtk::Label (M("TP_HLREC_METHOD"))); + hb->pack_start (*lab, Gtk::PACK_SHRINK, 4); + hb->pack_start (*method); + pack_start (*hb); + + enaconn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &HLRecovery::enabledChanged) ); + methconn = method->signal_changed().connect ( sigc::mem_fun(*this, &HLRecovery::methodChanged) ); + + show_all (); +} + +void HLRecovery::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + + if (pedited) + enabled->set_inconsistent (!pedited->hlrecovery.enabled); + enaconn.block (true); + enabled->set_active (pp->hlrecovery.enabled); + enaconn.block (false); + + if (pedited && !pedited->hlrecovery.method) + method->set_active (4); + else if (pp->hlrecovery.method=="Luminance") + method->set_active (0); + else if (pp->hlrecovery.method=="CIELab blending") + method->set_active (1); + else if (pp->hlrecovery.method=="Color") + method->set_active (2); + else if (pp->hlrecovery.method=="Blend") + method->set_active (3); + + lastEnabled = pp->hlrecovery.enabled; + + enableListener (); +} + +void HLRecovery::write (ProcParams* pp, ParamsEdited* pedited) { + + if (pedited) { + pedited->hlrecovery.method = method->get_active_row_number()!=4; + pedited->hlrecovery.enabled = !enabled->get_inconsistent(); + } + + pp->hlrecovery.enabled = enabled->get_active(); + if (method->get_active_row_number()==0) + pp->hlrecovery.method = "Luminance"; + else if (method->get_active_row_number()==1) + pp->hlrecovery.method = "CIELab blending"; + else if (method->get_active_row_number()==2) + pp->hlrecovery.method = "Color"; + else if (method->get_active_row_number()==3) + pp->hlrecovery.method = "Blend"; + +} + +void HLRecovery::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 (EvHREnabled, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvHREnabled, M("GENERAL_DISABLED")); + } +} + +void HLRecovery::methodChanged () { + + if (listener) { + if (enabled->get_active ()) + listener->panelChanged (EvHRMethod, method->get_active_text ()); + } +} + +void HLRecovery::setRaw (bool raw) { + + disableListener (); + set_sensitive (raw); + enableListener (); +} + +void HLRecovery::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + method->append_text (M("GENERAL_UNCHANGED")); +} diff --git a/rtgui/hlrec.h b/rtgui/hlrec.h new file mode 100644 index 000000000..b4e2ead06 --- /dev/null +++ b/rtgui/hlrec.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 _HLREC_H_ +#define _HLREC_H_ + +#include +#include "toolpanel.h" +#include "guiutils.h" + +class HLRecovery : public Gtk::VBox, public FoldableToolPanel { + + protected: + Gtk::CheckButton* enabled; + MyComboBoxText* method; + sigc::connection methconn; + sigc::connection enaconn; + bool lastEnabled; + + public: + + HLRecovery (); + + 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 setRaw (bool raw); + + void enabledChanged (); + void methodChanged (); +}; + +#endif diff --git a/rtgui/hsvequalizer.cc b/rtgui/hsvequalizer.cc new file mode 100644 index 000000000..89916e344 --- /dev/null +++ b/rtgui/hsvequalizer.cc @@ -0,0 +1,245 @@ +/* + * This file is part of RawTherapee. + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + * + * 2010 Ilya Popov + */ + +#include "hsvequalizer.h" +#include "../rtengine/color.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +HSVEqualizer::HSVEqualizer () : Gtk::VBox(), FoldableToolPanel(this) { + + 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..ae46a6217 --- /dev/null +++ b/rtgui/icmpanel.cc @@ -0,0 +1,589 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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); + + 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)); + + Gtk::Label* ilab = Gtk::manage (new Gtk::Label ()); + ilab->set_alignment (0.0, 0.5); + ilab->set_markup (Glib::ustring("") + M("TP_ICM_INPUTPROFILE") + ""); + pack_start (*ilab, Gtk::PACK_SHRINK, 4); + + inone = Gtk::manage (new Gtk::RadioButton (M("TP_ICM_INPUTNONE"))); + inone->set_tooltip_text (M("TP_ICM_INPUTNONE_TOOLTIP")); + pack_start (*inone, Gtk::PACK_SHRINK, 4); + + iembedded = Gtk::manage (new Gtk::RadioButton (M("TP_ICM_INPUTEMBEDDED"))); + iembedded->set_tooltip_text (M("TP_ICM_INPUTEMBEDDED_TOOLTIP")); + pack_start (*iembedded, Gtk::PACK_SHRINK, 4); + + icamera = Gtk::manage (new Gtk::RadioButton (M("TP_ICM_INPUTCAMERA"))); + icamera->set_tooltip_text (M("TP_ICM_INPUTCAMERA_TOOLTIP")); + pack_start (*icamera, Gtk::PACK_SHRINK, 4); + + icameraICC = Gtk::manage (new Gtk::RadioButton (M("TP_ICM_INPUTCAMERAICC"))); + icameraICC->set_tooltip_text (M("TP_ICM_INPUTCAMERAICC_TOOLTIP")); + pack_start (*icameraICC, Gtk::PACK_SHRINK, 4); + + 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); + + pack_start (*ffbox, Gtk::PACK_SHRINK, 4); + + 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 (); + Gtk::Label* ppl = Gtk::manage (new Gtk::Label (M("TP_ICM_PREFERREDPROFILE")+":")); + ppl->show (); + prefprof = Gtk::manage (new MyComboBoxText ()); + prefprof->append_text (M("TP_ICM_PREFERREDPROFILE_1")); + prefprof->append_text (M("TP_ICM_PREFERREDPROFILE_2")); + prefprof->append_text (M("TP_ICM_PREFERREDPROFILE_3")); + prefprof->append_text (M("TP_ICM_PREFERREDPROFILE_4")); + prefprof->show (); + hb->pack_start(*ppl, Gtk::PACK_SHRINK, 4); + hb->pack_start(*prefprof); + pack_start (*hb, Gtk::PACK_SHRINK, 4); + + ckbToneCurve = Gtk::manage (new Gtk::CheckButton (M("TP_ICM_TONECURVE"))); + ckbToneCurve->set_sensitive (false); + ckbToneCurve->set_tooltip_text (M("TP_ICM_TONECURVE_TOOLTIP")); + pack_start (*ckbToneCurve, Gtk::PACK_SHRINK, 4); + + ckbBlendCMSMatrix = Gtk::manage (new Gtk::CheckButton (M("TP_ICM_BLENDCMSMATRIX"))); + ckbBlendCMSMatrix->set_sensitive (false); + ckbBlendCMSMatrix->set_tooltip_text (M("TP_ICM_BLENDCMSMATRIX_TOOLTIP")); + pack_start (*ckbBlendCMSMatrix, Gtk::PACK_SHRINK, 4); + + saveRef = Gtk::manage (new Gtk::Button (M("TP_ICM_SAVEREFERENCE"))); + saveRef->set_image (*Gtk::manage (new RTImage ("gtk-save-large.png"))); + pack_start (*saveRef, Gtk::PACK_SHRINK, 4); + + + Gtk::HSeparator* hsep1 = Gtk::manage (new Gtk::HSeparator ()); + pack_start (*hsep1, Gtk::PACK_SHRINK, 2); + + Gtk::Label* wlab = Gtk::manage (new Gtk::Label ()); + wlab->set_alignment (0.0, 0.5); + wlab->set_markup (Glib::ustring("") + M("TP_ICM_WORKINGPROFILE") + ""); + + pack_start (*wlab, Gtk::PACK_SHRINK, 4); + wnames = Gtk::manage (new MyComboBoxText ()); + pack_start (*wnames, Gtk::PACK_SHRINK, 4); + + Gtk::HSeparator* hsep2 = Gtk::manage (new Gtk::HSeparator ()); + pack_start (*hsep2, Gtk::PACK_SHRINK, 2); + + Gtk::Label* olab = Gtk::manage (new Gtk::Label ()); + olab->set_alignment (0.0, 0.5); + olab->set_markup (Glib::ustring("") + M("TP_ICM_OUTPUTPROFILE") + ""); + + pack_start (*olab, Gtk::PACK_SHRINK, 4); + onames = Gtk::manage (new MyComboBoxText ()); + pack_start (*onames, Gtk::PACK_SHRINK, 4); + + std::vector wpnames = rtengine::getWorkingProfiles (); + for (size_t i=0; iappend_text (wpnames[i]); + + + Gtk::HSeparator* hsep22 = Gtk::manage (new Gtk::HSeparator ()); + pack_start (*hsep22, Gtk::PACK_SHRINK, 2); + + Gtk::Label* galab = Gtk::manage (new Gtk::Label ()); + galab->set_alignment (0.0, 0.5); + galab->set_markup (Glib::ustring("") + M("TP_GAMMA_OUTPUT") + ""); + + pack_start (*galab, Gtk::PACK_SHRINK, 4); + wgamma = Gtk::manage (new MyComboBoxText ()); + pack_start (*wgamma, Gtk::PACK_SHRINK, 4); + + Gtk::HSeparator* hsep23 = Gtk::manage (new Gtk::HSeparator ()); + pack_start (*hsep23, Gtk::PACK_SHRINK, 2); + + freegamma = Gtk::manage(new Gtk::CheckButton((M("TP_GAMMA_FREE")))); + freegamma->set_active (false); + pack_start( *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(); + pack_start( *gampos, Gtk::PACK_SHRINK, 4);//gamma + pack_start( *slpos, Gtk::PACK_SHRINK, 4);//slope + + + + std::vector wpgamma = rtengine::getGamma (); + for (size_t i=0; iappend_text (wpgamma[i]); + + 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]); + + wnames->set_active (0); + onames->set_active (0); + wgamma->set_active (0); + + 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) ); + prefprof->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::prefProfChanged) ); + + 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::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); prefprof->set_sensitive (false); ckbToneCurve->set_sensitive (false); + ckbBlendCMSMatrix->set_sensitive (false); + } + else if (pp->icm.input == "(embedded)" || ((pp->icm.input == "(camera)" || pp->icm.input=="") && icamera->get_state()==Gtk::STATE_INSENSITIVE)) { + iembedded->set_active (true); prefprof->set_sensitive (false); ckbToneCurve->set_sensitive (false); + ckbBlendCMSMatrix->set_sensitive (false); + } + else if ((pp->icm.input == "(cameraICC)") && icameraICC->get_state()!=Gtk::STATE_INSENSITIVE) { + icameraICC->set_active (true); prefprof->set_sensitive (true); ckbToneCurve->set_sensitive (true); + ckbBlendCMSMatrix->set_sensitive (true); + } + 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); + prefprof->set_sensitive (false); ckbToneCurve->set_sensitive (false); // RT's own are always single-illuminant and tone curve disabled + ckbBlendCMSMatrix->set_sensitive (false); + } + else if ((pp->icm.input == "(camera)" || pp->icm.input=="") && icamera->get_state()!=Gtk::STATE_INSENSITIVE) { + icamera->set_active (true); + ckbBlendCMSMatrix->set_sensitive (false); prefprof->set_sensitive (false); ckbToneCurve->set_sensitive (false); + } + 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); prefprof->set_sensitive (true); ckbToneCurve->set_sensitive (true); + } + + 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")); + + prefprof->set_active(pp->icm.preferredProfile-1); + + 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.preferredProfile) + prefprof->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.preferredProfile = prefprof->get_active_row_number()+1; + + 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.preferredProfile = prefprof->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::prefProfChanged() { + if (listener) + listener->panelChanged (EvPrefProfile, prefprof->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 () { + + std::string profname; + if (inone->get_active()) { + profname = "(none)"; + ckbBlendCMSMatrix->set_sensitive(false); prefprof->set_sensitive (false); ckbToneCurve->set_sensitive (false); + } + else if (iembedded->get_active ()) { + profname = "(embedded)"; + ckbBlendCMSMatrix->set_sensitive(false); prefprof->set_sensitive (false); ckbToneCurve->set_sensitive (false); + } + else if (icamera->get_active ()) { + profname = "(camera)"; + ckbBlendCMSMatrix->set_sensitive(false); prefprof->set_sensitive (false); ckbToneCurve->set_sensitive (false); + } + else if (icameraICC->get_active ()) { + profname = "(cameraICC)"; + ckbBlendCMSMatrix->set_sensitive(true); prefprof->set_sensitive (false); ckbToneCurve->set_sensitive (false); + } + else { + profname = ipDialog->get_filename (); + ckbBlendCMSMatrix->set_sensitive(true); prefprof->set_sensitive (true); ckbToneCurve->set_sensitive (true); + } + + 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_SAVEREFERENCEDLGLABEL"), 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) { + + ToolPanel::setBatchMode (batchMode); + iunchanged = Gtk::manage (new Gtk::RadioButton (M("GENERAL_UNCHANGED"))); + iunchanged->set_group (opts); + pack_start (*iunchanged, Gtk::PACK_SHRINK, 4); + 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")); + prefprof->append_text (M("GENERAL_UNCHANGED")); + gampos->showEditedCB (); + slpos->showEditedCB (); + +} + diff --git a/rtgui/icmpanel.h b/rtgui/icmpanel.h new file mode 100644 index 000000000..4c3838dac --- /dev/null +++ b/rtgui/icmpanel.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 _ICMPANEL_ +#define _ICMPANEL_ + +#include + +#include +#include "adjuster.h" +#include "guiutils.h" + +#include "toolpanel.h" +#include "../rtengine/imagedata.h" + +class ICMPanelListener { + + public: + 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; + sigc::connection blendcmsconn; + + private: + Gtk::CheckButton* freegamma; + Gtk::RadioButton* inone; + + Gtk::RadioButton* iembedded; + Gtk::RadioButton* icamera; + Gtk::RadioButton* icameraICC; + Gtk::RadioButton* ifromfile; + MyComboBoxText* prefprof; + 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 enableLastICCWorkDirChange; + Glib::ustring lastRefFilename; + + 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 prefProfChanged(); + 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..e56fc44ea --- /dev/null +++ b/rtgui/imagearea.cc @@ -0,0 +1,476 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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(); + + 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); + + 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) + return listener->getToolBar()->getTool (); + else + return TMHand; +} + +void ImageArea::setToolHand () { + + if (listener) + 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..7e7900b43 --- /dev/null +++ b/rtgui/imageareatoollistener.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 _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 CropGUIListener* startCropEditing (Thumbnail* thm=NULL) { return NULL; } +}; + +#endif + diff --git a/rtgui/impulsedenoise.cc b/rtgui/impulsedenoise.cc new file mode 100644 index 000000000..70ab7315d --- /dev/null +++ b/rtgui/impulsedenoise.cc @@ -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 . + */ +#include "impulsedenoise.h" +#include +#include +#include "guiutils.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +ImpulseDenoise::ImpulseDenoise () : Gtk::VBox(), FoldableToolPanel(this) { + + 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..6a9bfd5ac --- /dev/null +++ b/rtgui/iptcpanel.cc @@ -0,0 +1,588 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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")); + 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); + 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); + 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..e45e13cc3 --- /dev/null +++ b/rtgui/labcurve.cc @@ -0,0 +1,510 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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) { + + 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.)); + + pack_start (*brightness); + brightness->show (); + + pack_start (*contrast); + contrast->show (); + + pack_start (*chromaticity); + chromaticity->show (); + + brightness->setAdjusterListener (this); + contrast->setAdjusterListener (this); + chromaticity->setAdjusterListener (this); + + //%%%%%%%%%%%%%%%%%% + pack_start (*Gtk::manage (new Gtk::HSeparator())); + + bwtoning = Gtk::manage (new Gtk::CheckButton (M("TP_LABCURVE_BWTONING"))); + bwtoning->set_tooltip_markup (M("TP_LABCURVE_BWTONING_TIP")); + pack_start (*bwtoning); + + 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")); + + bwtconn= bwtoning->signal_toggled().connect( sigc::mem_fun(*this, &LCurve::bwtoning_toggled) ); + 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); + + curveEditorG = new CurveEditorGroup (options.lastLabCurvesDir); + curveEditorG->setCurveListener (this); + + lshape = static_cast(curveEditorG->addCurve(CT_Diagonal, "L")); + 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") + ); + 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") + ); + + curveEditorG->newLine(); // ------------------------------------------------ second 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); + + chshape = static_cast(curveEditorG->addCurve(CT_Flat, M("TP_LABCURVE_CURVEEDITOR_CH"))); + chshape->setTooltip(M("TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP")); + chshape->setCurveColorProvider(this, 1); + + 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, 3); + 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.15, 0.3, 0.6); + + // 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.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); + + + // 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(!pp->labCurve.cccurve.empty()) printf("plein"); else printf("vide"); + // if(pp->labCurve.cccurve[0] !=0) printf(" pp %i\n,pp->labCurve.cccurve[0] "); + + 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); + bwtoning->set_inconsistent (!pedited->labCurve.bwtoning); + 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); + lcshape->setUnChanged (!pedited->labCurve.lccurve); + } + else { + //if bwtoning is enabled, chromaticity value, avoid color shift and rstprotection has no effect + //ccshape->set_sensitive(!(!pp->labCurve.bwtoning)); + //chshape->set_sensitive(!(!pp->labCurve.bwtoning)); + chromaticity->set_sensitive(!pp->labCurve.bwtoning); + rstprotection->set_sensitive( !pp->labCurve.bwtoning /*&& pp->labCurve.chromaticity!=0*/ );//no reason for grey rstprotection + avoidcolorshift->set_sensitive(!pp->labCurve.bwtoning); + lcredsk->set_sensitive(!pp->labCurve.bwtoning); + + std::vector milestones; + lcshape->setBottomBarBgGradient(milestones); + lcshape->refresh(); + } + + brightness->setValue (pp->labCurve.brightness); + contrast->setValue (pp->labCurve.contrast); + chromaticity->setValue (pp->labCurve.chromaticity); + + //%%%%%%%%%%%%%%%%%%%%%% + rstprotection->setValue (pp->labCurve.rstprotection); + + bwtconn.block (true); + acconn.block (true); + lcconn.block (true); + bwtoning->set_active (pp->labCurve.bwtoning); + avoidcolorshift->set_active (pp->labCurve.avoidcolorshift); + lcredsk->set_active (pp->labCurve.lcredsk); + + bwtconn.block (false); + acconn.block (false); + lcconn.block (false); + + lastBWTVal = pp->labCurve.bwtoning; + 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); + lcshape->setCurve (pp->labCurve.lccurve); + + 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) lcshape->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.bwtoning = bwtoning->get_active (); + 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.lccurve = lcshape->getCurve (); + + if (pedited) { + pedited->labCurve.brightness = brightness->getEditedState (); + pedited->labCurve.contrast = contrast->getEditedState (); + pedited->labCurve.chromaticity = chromaticity->getEditedState (); + + //%%%%%%%%%%%%%%%%%%%%%% + pedited->labCurve.bwtoning = !bwtoning->get_inconsistent(); + 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.lccurve = !lcshape->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")); + } +} + + +//%%%%%%%%%%%%%%%%%%%%%% +//BW toning control changed +void LCurve::bwtoning_toggled () { + + if (batchMode) { + if (bwtoning->get_inconsistent()) { + bwtoning->set_inconsistent (false); + bwtconn.block (true); + bwtoning->set_active (false); + bwtconn.block (false); + } + else if (lastBWTVal) + bwtoning->set_inconsistent (true); + + lastBWTVal = bwtoning->get_active (); + } + else { + //ccshape->set_sensitive(!(!pp->labCurve.bwtoning)); + //chshape->set_sensitive(!(!pp->labCurve.bwtoning)); + chromaticity->set_sensitive( !(bwtoning->get_active ()) ); + rstprotection->set_sensitive( !(bwtoning->get_active ()) /*&& chromaticity->getIntValue()!=0*/); + avoidcolorshift->set_sensitive( !(bwtoning->get_active ()) ); + lcredsk->set_sensitive( !(bwtoning->get_active ()) ); + + } + + if (listener) { + if (bwtoning->get_active ()) + listener->panelChanged (EvLBWtoning, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvLBWtoning, 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 == lcshape) + listener->panelChanged (EvLLCCurve, M("HISTORY_CUSTOMCURVE")); + } +} + +void LCurve::adjusterChanged (Adjuster* a, double newval) { + + if (!listener) + return; + + 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) + listener->panelChanged (EvLBrightness, costr); + else if (a==contrast) + listener->panelChanged (EvLContrast, costr); + else if (a==chromaticity) { + if (!batchMode) { + rstprotection->set_sensitive( !(bwtoning->get_active ())/* && chromaticity->getIntValue()!=0*/ ); + } + listener->panelChanged (EvLSaturation, costr); + } + else if (a==rstprotection) + listener->panelChanged (EvLRSTProtection, 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); + } + } + 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 & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma){ + + lshape->updateBackgroundHistogram (histLCurve); +} + +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..91fc56402 --- /dev/null +++ b/rtgui/labcurve.h @@ -0,0 +1,78 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#ifndef _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; + + //%%%%%%%%%%%%%%%% + Gtk::CheckButton* avoidcolorshift; + Gtk::CheckButton* bwtoning; + Gtk::CheckButton* lcredsk; + + Adjuster* rstprotection; + sigc::connection bwtconn, acconn, lcconn; + bool lastBWTVal, 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 bwtoning_toggled(); + void lcredsk_toggled(); + + void updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, 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..abeb469f0 --- /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" + +extern Glib::ustring argv0; + +using namespace rtengine; +using namespace rtengine::procparams; + +LensGeometry::LensGeometry () : Gtk::VBox(), FoldableToolPanel(this), rlistener(NULL) { + + fill = Gtk::manage (new Gtk::CheckButton (M("TP_LENSGEOM_FILL"))); + pack_start (*fill); + + autoCrop = Gtk::manage (new Gtk::Button (M("TP_LENSGEOM_AUTOCROP"))); + autoCrop->set_image (*Gtk::manage (new RTImage ("crop-auto.png"))); + pack_start (*autoCrop, Gtk::PACK_SHRINK, 2); + + packBox = Gtk::manage (new 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..5a3c4bbbf --- /dev/null +++ b/rtgui/lensprofile.cc @@ -0,0 +1,170 @@ +/* +* 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) +{ + 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.length()>0 && lcpStore->isValidLCPFileName(pp->lensProf.lcpFile)) { + fcbLCPFile->set_filename (pp->lensProf.lcpFile); + updateDisabled(true); + } else { + fcbLCPFile->unselect_filename(fcbLCPFile->get_filename()); + 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..628c7fa6e --- /dev/null +++ b/rtgui/lwbutton.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 "lwbutton.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) { + + 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..23ff322a6 --- /dev/null +++ b/rtgui/lwbutton.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 _LWBUTTON_ +#define _LWBUTTON_ + +#include + +class LWButton; +class LWButtonListener { + + public: + 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..b024e0914 --- /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..8934257b4 --- /dev/null +++ b/rtgui/main.cc @@ -0,0 +1,523 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 "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 +#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; + +/* 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,""); +#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 + + Glib::thread_init(); + gdk_threads_init(); + Gio::init (); + + Options::load (); + extProgStore->init(); + SoundManager::init(); + + if (argc>1){ + int ret = processLineParams( argc, argv); + if( ret <= 0 ) + return ret; + } + +#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 + + + RTWindow *rtWindow = new class RTWindow(); + gdk_threads_enter (); + + // 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(); + 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::cerr << "RawTherapee, V" << VERSION << std::endl; + std::cerr << "Copyright (c)2004-2012 Gabor Horvath "<< std::endl << std::endl; + std::cerr << "Usage:"<< std::endl; + std::cerr << Glib::path_get_basename(argv[0]) << " [] : start RT GUI browser inside dir."<< std::endl; + std::cerr << Glib::path_get_basename(argv[0]) << " : start GUI editor with file."<< std::endl; + std::cerr << Glib::path_get_basename(argv[0]) << " -c | : convert files in batch with default parameters."<< std::endl<< std::endl; + std::cerr << "Other options used with -c (that must be last option) "<< std::endl; + std::cerr << Glib::path_get_basename(argv[0]) <<" [-o | -O ] [-s|-S] [-p ] [-d] [-j[1-100]|-t|-n] -Y -c "<< std::endl; + std::cerr << " -o | : select output directory."<< std::endl; + std::cerr << " -O | : select output dir and copy " << pparamsExt << " file into it"<< std::endl; + std::cerr << " -s : include the " << pparamsExt << " file next to the input file (with same name) to build the image's parameters"<< std::endl; + std::cerr << " ex: for IMG001.NEF there should be IMG001.NEF." << pparamsExt << " in the same dir" << std::endl; + std::cerr << " if absent use default" << std::endl; + std::cerr << " -S : like -s but skip if " << pparamsExt << " file not found." << std::endl; + std::cerr << " -p : specify " << pparamsExt << " file to be used for all conversions."<< std::endl; + std::cerr << " you can specify as much -p option as you want (see the note below)."<< std::endl; + std::cerr << " -d : use the default Raw or Image " << pparamsExt << " file to build the image's parameters"<< std::endl; + std::cerr << " -j[compression] : specify output to be jpeg.(default)"<< std::endl; + std::cerr << " -t : specify output to be uncompressed tiff."<< std::endl; + std::cerr << " -t1: specify output to be compressed tiff."<< std::endl; + std::cerr << " -n : specify output to be png."<< std::endl; + std::cerr << " -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..0b44abe39 --- /dev/null +++ b/rtgui/multilangmgr.cc @@ -0,0 +1,185 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#include +#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 +#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()) { + + // TODO: Add support for other OS here +#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 +#endif + } else printf("Automatic language detection not supported on your OS\n"); + + 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..2f2dc500a --- /dev/null +++ b/rtgui/multilangmgr.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 _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..5ba6d11ec --- /dev/null +++ b/rtgui/mycurve.cc @@ -0,0 +1,115 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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); + 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); + 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::snapCoordinate(double testedVal, double realVal) { + + double distY = realVal - testedVal; + + if (distY < 0.) distY = -distY; + if (distY < snapToMinDist) { + snapToMinDist = distY; + snapToVal = 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..4d33e21c5 --- /dev/null +++ b/rtgui/mycurve.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 _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 */ + +// 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 +}; + +enum SnapToType { + ST_None, + ST_Identity, // Point snapped to the identity curve + ST_Neighbors // Point snapped to the neighbor points +}; + +enum ResizeState { + RS_Pending = 1, // Resize has to occure + RS_Done = 2, // Resize has been done + RS_Force = 4 // Resize has to occure 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 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 snapToMinDist; + double snapToVal; + MyCurveIdleHelper* mcih; + enum ResizeState sized; + bool curveIsDirty; + + virtual std::vector get_vector (int veclen) = 0; + int getGraphMinSize() { return GRAPH_SIZE + RADIUS + 1; } + bool snapCoordinate(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 () = 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..9456142e7 --- /dev/null +++ b/rtgui/mydiagonalcurve.cc @@ -0,0 +1,848 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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) { + + snapToMinDist = 10.; + snapToVal = 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 (snapCoordinate(y, ugpY)) snapToElmt = 1000+grab_point; + } + if (grab_point > 0) { + int prevP = grab_point-1; + if (snapCoordinate(curve.y[prevP], ugpY)) snapToElmt = prevP; + } + if (grab_point < (curve.y.size()-1)) { + int nextP = grab_point+1; + if (snapCoordinate(curve.y[nextP], ugpY)) snapToElmt = nextP; + } + if (snapCoordinate(1.0, ugpY)) snapToElmt = -3; + if (snapCoordinate(curve.x[grab_point], ugpY)) snapToElmt = -2; + if (snapCoordinate(0.0, ugpY)) snapToElmt = -1; + + curve.y[grab_point] = snapToVal; + } + 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++; + g_idle_add (diagonalmchistupdateUI, mcih); + +} + +void MyDiagonalCurve::reset() { + + 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..5ab2ed35a --- /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 (); + void updateBackgroundHistogram (LUTu & hist); +}; + +#endif diff --git a/rtgui/myflatcurve.cc b/rtgui/myflatcurve.cc new file mode 100644 index 000000000..c2f65c457 --- /dev/null +++ b/rtgui/myflatcurve.cc @@ -0,0 +1,1266 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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.) { + + cr->set_line_width (1.0); + 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 (4.0); + } + 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 (1.0); + + // 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 (4.0); + } + + 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 (); + + int previous_lit_point = lit_point; + + // 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; + } + + if ((lit_point != previous_lit_point) || (prevArea != area)) { + 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; + + snapToMinDist = 10.; + snapToVal = 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) { + snapCoordinate(0.0, ugpX); + snapCoordinate(0.35, ugpX); + snapCoordinate(0.5, ugpX); + snapCoordinate(1.0, ugpX); + curve.leftTangent[lit_point] = snapToVal; + } + 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) { + snapCoordinate(0.0, ugpX); + snapCoordinate(0.35, ugpX); + snapCoordinate(0.5, ugpX); + snapCoordinate(1.0, ugpX); + curve.rightTangent[lit_point] = snapToVal; + } + 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 ? curve.x[nbPoints-1]-1. : 0.) : curve.x[lit_point-1]; + rightBound = (lit_point == nbPoints-1) ? (periodic ? 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 (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) { + curve.x[lit_point] = -1.; + } + else if (ugpX <= leftDeletionBound && nbPoints>2) { + 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 (snapCoordinate(curve.y[prevP], ugpY)) snapToElmt = prevP; + } + else { + int prevP = lit_point-1; + if (snapCoordinate(curve.y[prevP], ugpY)) snapToElmt = prevP; + } + + if (curve.y.size() > 2) { + if (lit_point == (curve.y.size()-1)) { + if (snapCoordinate(curve.y[0], ugpY)) snapToElmt = 0; + } + else { + int nextP = lit_point+1; + if (snapCoordinate(curve.y[nextP], ugpY)) snapToElmt = nextP; + } + } + if (snapCoordinate(1.0, ugpY)) snapToElmt = -3; + if (snapCoordinate(0.5, ugpY)) snapToElmt = -2; + if (snapCoordinate(0.0, ugpY)) snapToElmt = -1; + + curve.y[lit_point] = snapToVal; + } + + // 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() { + calcDimensions(); + + switch (curve.type) { + case FCT_MinMaxCPoints : + defaultCurve(); + lit_point = -1; + curveIsDirty = true; + break; + //case Parametric : + // Nothing to do (?) + default: + break; + } + setDirty(true); + draw(); +} + +void MyFlatCurve::defaultCurve () { + + 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) = 0.5; + 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..dc6a2c8b8 --- /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 (); + 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 (); + //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..432d3bc89 --- /dev/null +++ b/rtgui/options.cc @@ -0,0 +1,1110 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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, "")) { + int retVal = safe_g_mkdir_with_parents (profilePath, 511); + if (!retVal) + 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; + if (useBundledProfiles) { + 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, "")) { + int retVal = safe_g_mkdir_with_parents (tmpPath, 511); + if (!retVal) + 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; + } + if (useBundledProfiles) { + 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 (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; +} + +Glib::ustring Options::getPreferredProfilePath() { + if (!userProfilePath.empty()) + return userProfilePath; + else if (!globalProfilePath.empty()) + return globalProfilePath; + else + return ""; +} + +Glib::ustring Options::findProfilePath(Glib::ustring &profName) { + if (profName.empty()) + return ""; + + Glib::ustring p = getUserProfilePath(); + Glib::ustring fullPath = Glib::build_filename(p, profName + paramFileExtension); + if (!p.empty() && safe_file_test (fullPath, Glib::FILE_TEST_EXISTS)) + return p; + + p = getGlobalProfilePath(); + fullPath = Glib::build_filename(p, profName + paramFileExtension); + if (!p.empty() && safe_file_test (fullPath, Glib::FILE_TEST_EXISTS)) + return p; + else + return ""; + +} + +void Options::setDefaults () { + + font = "sans, 8"; + windowWidth = 900; + windowHeight = 560; + windowMaximized = false; + saveAsDialogWidth = 600; + saveAsDialogHeight = 600; + 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 = 8; + 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 = 200; + dirBrowserHeight = 150; + preferencesWidth = 0; + preferencesHeight = 0; + toolPanelWidth = 300; + browserToolPanelWidth = 300; + browserToolPanelHeight = 300; + historyPanelWidth = 230; + lastScale = 5; + panAccelFactor = 5; + lastCropSize = 1; + fbOnlyRaw = false; + fbShowDateTime = true; + fbShowBasicExif = true; + fbShowExpComp = true; + 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 = 80; + 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; + thumbnailFormat = FT_Custom; // was FT_Custom16 + thumbInterp = 1; + autoSuffix = false; + 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 = true; + internalThumbIfUntouched = true; // if TRUE, only fast, internal preview images are taken if the image is not edited yet + showFileNames = true; + tabbedUI = true; + multiDisplayMode = 0; + tunnelMetaData = false; + histogramPosition = 2; + histogramBar = true; + histogramFullMode = false; + 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_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 = "sRGB"; + 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 = 1000; + fastexport_resize_height = 1000; + + cutOverlayBrush = std::vector (4); + cutOverlayBrush[3] = 0.667; // :-p + + sndEnable=true; + sndLngEditProcDoneSecs=3.0; + + // 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_CHLUM + 0, // ADDSET_DIRPYRDN_GAMMA + 0, // ADDSET_CHMIXER + 0, // ADDSET_PREPROCESS_GREENEQUIL + 0, // ADDSET_PREPROCESS_LINEDENOISE + 0, // ADDSET_RAWCACORR + 0, // ADDSET_RAWEXPOS_LINEAR + 0, // ADDSET_RAWEXPOS_PRESER + 0, // ADDSET_RAWEXPOS_BLACKS + 0, // ADDSET_SHARPENEDGE_AMOUNT + 0, // ADDSET_SHARPENMICRO_AMOUNT + 0, // ADDSET_SHARPENEDGE_PASS + 0, // ADDSET_SHARPENMICRO_UNIFORMITY + 0, // ADDSET_VIBRANCE_PASTELS + 0, // ADDSET_VIBRANCE_SATURATED + 0, // ADDSET_FREE_OUPUT_GAMMA + 0, // ADDSET_FREE_OUTPUT_SLOPE + + }; + 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"; +#else + rtSettings.iccDirectory = "/usr/share/color/icc"; +#endif + rtSettings.colorimetricIntent = 1; + 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.protectred = 60; + rtSettings.protectredh = 0.3; + + lastIccDir = rtSettings.iccDirectory; + lastDarkframeDir = rtSettings.darkFramesPath; + lastFlatfieldDir = rtSettings.flatFieldsPath; + + // 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 = ""; + lastHsvCurvesDir = ""; + lastToneCurvesDir = ""; + lastVibranceCurvesDir = ""; + lastProfilingReferenceDir = ""; +} + +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_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_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", "SaveParamsWithFile", saveParamsFile); + keyFile.set_boolean ("Profiles", "SaveParamsToCache", saveParamsCache); + keyFile.set_integer ("Profiles", "LoadParamsFromLocation", paramsLoadLocation); + keyFile.set_string ("Profiles", "CustomProfileBuilder", customProfileBuilder); + + 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_integer ("Color Management", "Intent", rtSettings.colorimetricIntent); + 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", "GamutLch", rtSettings.gamutLch); + keyFile.set_integer ("Color Management", "ProtectRed", rtSettings.protectred); + keyFile.set_double ("Color Management", "ProtectRedH", rtSettings.protectredh); + + 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_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", "LastHsvCurvesDir", lastHsvCurvesDir); + 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) + 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::ustring(pathA) + Glib::ustring("\\") + Glib::ustring(CACHEFOLDERNAME); + } + } +#else + rtdir = Glib::ustring(g_get_user_config_dir ()) + Glib::ustring("/") + Glib::ustring(CACHEFOLDERNAME); +#endif + + // Set the cache folder in RT's base folder + cacheBaseDir = argv0 + "/cache"; + + // Read the global option file (the one located in the application's base folder) + options.readFromFile (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 (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 (rtdir + "/options"); + } + // Modify the path of the cache folder to the user's personal folder +#ifdef WIN32 + cacheBaseDir = rtdir + "/cache"; +#else + cacheBaseDir = Glib::ustring(g_get_user_cache_dir()) + Glib::ustring("/") + Glib::ustring(CACHEFOLDERNAME); +#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); +} + +void Options::save () { + + if (options.multiUser==false) { + options.saveToFile (argv0+"/options"); + } + else { + options.saveToFile (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..90378546e --- /dev/null +++ b/rtgui/options.h @@ -0,0 +1,274 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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 +#define DEFPROFILE_RAW "Default" +// Default bundled profile name to use for Standard images +#define DEFPROFILE_IMG "Neutral" +// Profile name to use for internal values' profile +#define DEFPROFILE_INTERNAL "Internal" + +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}; + +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; + 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; + int saveMethodNum; + bool saveParamsFile; + bool saveParamsCache; + PPLoadLocation paramsLoadLocation; + bool procQueueEnabled; + Glib::ustring gimpDir; + Glib::ustring psDir; + Glib::ustring customEditorProg; + Glib::ustring customProfileBuilder; + 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; + + 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_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 lastHsvCurvesDir; + Glib::ustring lastToneCurvesDir; + Glib::ustring lastVibranceCurvesDir; + Glib::ustring lastProfilingReferenceDir; + + 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; } +}; + +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..fca23965c --- /dev/null +++ b/rtgui/paramsedited.cc @@ -0,0 +1,664 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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; + labCurve.lcurve = v; + labCurve.acurve = v; + labCurve.bcurve = v; + labCurve.cccurve = v; + labCurve.chcurve = v; + labCurve.lccurve = v; + labCurve.brightness = v; + labCurve.contrast = v; + labCurve.chromaticity = v; + labCurve.avoidcolorshift = v; + labCurve.rstprotection = v; + labCurve.bwtoning = v; + labCurve.lcredsk = 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; + //colorBoost.amount = v; + //colorBoost.avoidclip = v; + //colorBoost.enable_saturationlimiter = v; + //colorBoost.saturationlimit = v; + wb.method = v; + wb.green = v; + wb.temperature = 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; + impulseDenoise.enabled = v; + impulseDenoise.thresh = v; + dirpyrDenoise.enabled = v; + dirpyrDenoise.luma = v; + dirpyrDenoise.Ldetail = v; + dirpyrDenoise.chroma = v; + dirpyrDenoise.gamma = 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; + 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; + hlrecovery.enabled = v; + hlrecovery.method = 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.preferredProfile = 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.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; + } + 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 && 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..86b509ae9 --- /dev/null +++ b/rtgui/paramsedited.h @@ -0,0 +1,428 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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; +}; + +class LCurveParamsEdited { + + public: + bool brightness; + bool contrast; + bool chromaticity; + bool avoidcolorshift; + bool rstprotection; + bool lcurve; + bool acurve; + bool bcurve; + bool bwtoning; + bool lcredsk; + bool cccurve; + bool chcurve; + bool lccurve; +}; + +class RGBCurvesParamsEdited { + + public: + 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; +}; + +/*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; +}; + +class ImpulseDenoiseParamsEdited { + +public: + bool enabled; + bool thresh; + +}; + +class DirPyrDenoiseParamsEdited { + +public: + bool enabled; + bool Ldetail; + bool luma; + bool chroma; + bool gamma; +}; + +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 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 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 preferredProfile; + bool working; + bool output; + bool gamma; + bool gampos; + bool slpos; + bool gamfree; + bool freegamma; +}; + +class DirPyrEqualizerParamsEdited { + +public: + bool enabled; + bool mult[8]; +}; + +class HSVEqualizerParamsEdited { + +public: + bool hcurve; + bool scurve; + bool vcurve; +}; + +class RAWParamsEdited { + + public: + bool ccSteps; + bool dmethod; + bool dcbIterations; + bool dcbEnhance; + 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; + //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; + CACorrParamsEdited cacorrection; + VignettingParamsEdited vignetting; + ChannelMixerParamsEdited chmixer; + HRecParamsEdited hlrecovery; + 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..004ab563e --- /dev/null +++ b/rtgui/partialpastedlg.cc @@ -0,0 +1,654 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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"))); + hlrec = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_HLRECONSTRUCTION"))); + sh = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_SHADOWSHIGHLIGHTS"))); + epd = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_EPD"))); + labcurve = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_LABCURVE"))); + + // 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"))); + 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"))); + + 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 (*hlrec, 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 (*labcurve, 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 (*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_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)); + hlrecConn = hlrec->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)); + labcurveConn = labcurve->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)); + 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_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_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_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_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); + hlrecConn.block (true); + shConn.block (true); + epdConn.block(true); + labcurveConn.block (true); + + basic->set_inconsistent (false); + + wb->set_active (basic->get_active ()); + exposure->set_active (basic->get_active ()); + hlrec->set_active (basic->get_active ()); + sh->set_active (basic->get_active ()); + epd->set_active (basic->get_active ()); + labcurve->set_active (basic->get_active ()); + + wbConn.block (false); + exposureConn.block (false); + hlrecConn.block (false); + shConn.block (false); + epdConn.block (false); + labcurveConn.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); + 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 ()); + hsveq->set_active (color->get_active ()); + rgbcurves->set_active (color->get_active ()); + icm->set_active (color->get_active ()); + + vibranceConn.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 (!hlrec->get_active ()) filterPE.hlrecovery = falsePE.hlrecovery; + if (!sh->get_active ()) filterPE.sh = falsePE.sh; + if (!epd->get_active ()) filterPE.edgePreservingDecompositionUI = falsePE.edgePreservingDecompositionUI; + if (!labcurve->get_active ()) filterPE.labCurve = falsePE.labCurve; + + 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 (!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_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..a25b57dd5 --- /dev/null +++ b/rtgui/partialpastedlg.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 _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* hlrec; + Gtk::CheckButton* sh; + Gtk::CheckButton* epd; + Gtk::CheckButton* labcurve; + + // 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* 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* 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, hlrecConn, shConn, labcurveConn; + sigc::connection sharpenConn, gradsharpenConn, microcontrastConn, impdenConn, dirpyrdenConn, waveqConn, defringeConn, epdConn, dirpyreqConn; + sigc::connection vibranceConn, chmixerConn, hsveqConn, rgbcurvesConn; + 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_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/perspective.cc b/rtgui/perspective.cc new file mode 100644 index 000000000..7882d69fa --- /dev/null +++ b/rtgui/perspective.cc @@ -0,0 +1,102 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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" + +using namespace rtengine; +using namespace rtengine::procparams; + +PerspCorrection::PerspCorrection () : Gtk::VBox(), FoldableToolPanel(this) { + + horiz = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_HORIZONTAL"), -100, 100, 1, 0)); + horiz->setAdjusterListener (this); + + vert = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_VERTICAL"), -100, 100, 1, 0)); + 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..f0d650a90 --- /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 (Glib::get_home_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 */ } + } + + // 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..14cc865a7 --- /dev/null +++ b/rtgui/pparamschangelistener.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 _PPARAMSCHANGELISTENER_ +#define _PPARAMSCHANGELISTENER_ + +#include "../rtengine/rtengine.h" +#include +#include "paramsedited.h" + +class PParamsChangeListener { + + public: + virtual void procParamsChanged (rtengine::procparams::ProcParams* params, rtengine::ProcEvent ev, Glib::ustring descr, ParamsEdited* paramsEdited=NULL) {} + virtual void clearParamChanges () {} +}; + +#endif + diff --git a/rtgui/ppversion.h b/rtgui/ppversion.h new file mode 100644 index 000000000..5f104071b --- /dev/null +++ b/rtgui/ppversion.h @@ -0,0 +1,8 @@ +#ifndef _PPVERSION_ +#define _PPVERSION_ + +// This number have to be incremented whenever the PP3 file format is modified +#define PPVERSION 305 +#define PPVERSION_AEXP 301 //value of PPVERSION when auto exposure algorithm was modified + +#endif diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc new file mode 100644 index 000000000..7a7be63e3 --- /dev/null +++ b/rtgui/preferences.cc @@ -0,0 +1,1498 @@ +/* + * 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):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 (*getSoundPanel(), M("PREFERENCES_TAB_SOUND")); + nb->set_current_page (0); + + fillPreferences (); + + show_all_children (); + set_modal (true); +} + + +Preferences::~Preferences () { + + 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::Frame* behFrame = Gtk::manage (new Gtk::Frame (M("PREFERENCES_BEHAVIOR"))); + behFrame->add (*behscrollw); + //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_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); + + 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_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_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")+", "+M("TP_DIRPYREQUALIZER_THRESHOLD"), ADDSET_DIRPYREQ, 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 (); + + 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::Label* drlab = Gtk::manage (new Gtk::Label (M("PREFERENCES_FORRAW")+":", Gtk::ALIGN_LEFT)); + rprofiles = Gtk::manage (new Gtk::ComboBoxText ()); + rprofiles->set_size_request(50, -1); + rprofiles->signal_changed().connect( sigc::mem_fun(*this, &Preferences::forRAWComboChanged) ); + forRAWComboChanged(); // update the tooltip + Gtk::Label* drimg = Gtk::manage (new Gtk::Label (M("PREFERENCES_FORIMAGE")+":", Gtk::ALIGN_LEFT)); + iprofiles = Gtk::manage (new Gtk::ComboBoxText ()); + iprofiles->set_size_request(50, -1); + iprofiles->signal_changed().connect( sigc::mem_fun(*this, &Preferences::forImageComboChanged) ); + forImageComboChanged(); // update the tooltip + 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); + fpp->add (*defpt); + + mvbpp->pack_start (*fpp, 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); + + std::vector pnames; + parseDir (options.getUserProfilePath(), pnames, paramFileExtension); + parseDir (options.getGlobalProfilePath(), pnames, paramFileExtension); + for (size_t i=0; iappend_text (pnames[i]); + iprofiles->append_text (pnames[i]); + } + + 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::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); + 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); + mvbcm->pack_start (*colt, Gtk::PACK_SHRINK, 4); + + autoMonProfileToggled(); + + 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)); + hb6->pack_start (*dflab, Gtk::PACK_SHRINK,4); + 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); + + + // Custom profile builder box + Gtk::Frame* cpfrm = Gtk::manage( new Gtk::Frame (M("PREFERENCES_CUSTPROFBUILD")) ); + + Gtk::HBox* cphb = Gtk::manage( new Gtk::HBox () ); + cphb->set_border_width (4); + cphb->set_spacing (4); + + Gtk::Label* cplab = Gtk::manage( new Gtk::Label (M("PREFERENCES_CUSTPROFBUILDPATH")+":") ); + cphb->pack_start (*cplab, Gtk::PACK_SHRINK,4); + + txtCustProfBuilderPath = Gtk::manage( new Gtk::Entry () ); + txtCustProfBuilderPath->set_tooltip_markup (M("PREFERENCES_CUSTPROFBUILDHINT")); + cphb->set_tooltip_markup (M("PREFERENCES_CUSTPROFBUILDHINT")); + cphb->pack_start (*txtCustProfBuilderPath); + + cpfrm->add (*cphb); + + mvbsd->pack_start (*cpfrm, 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::Label* cflab = Gtk::manage( new Gtk::Label (M("PREFERENCES_CACHETHUMBFORM")+":") ); + cflab->set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_TOP); + cformat = Gtk::manage( new Gtk::ComboBoxText () ); + cformat->set_size_request(50, -1); + cformat->append_text (M("PREFERENCES_CACHEFORMAT1")); + cformat->append_text (M("PREFERENCES_CACHEFORMAT2")); + cformat->append_text (M("PREFERENCES_CACHEFORMAT1")+", 16 bit"); + cformat->signal_changed().connect( sigc::mem_fun(*this, &Preferences::cacheFormatComboChanged) ); + cacheFormatComboChanged(); // update the tooltip + vbc->pack_start (*cflab, Gtk::PACK_SHRINK, 2); + vbc->pack_start (*cformat); + + 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())); + } + delete dir; +} + +void Preferences::storePreferences () { + + moptions.defProfRaw = rprofiles->get_active_text(); + if (moptions.defProfRaw.empty()) moptions.defProfRaw = DEFPROFILE_RAW; + moptions.defProfImg = iprofiles->get_active_text(); + if (moptions.defProfImg.empty()) moptions.defProfImg = DEFPROFILE_IMG; + 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.customProfileBuilder = txtCustProfBuilderPath->get_text(); + + moptions.rtSettings.monitorProfile = monProfile->get_filename (); + moptions.rtSettings.autoMonitorProfile = cbAutoMonProfile->get_active (); + moptions.rtSettings.iccDirectory = iccDir->get_current_folder (); + moptions.rtSettings.colorimetricIntent = intent->get_active_row_number (); + + 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_active_row_number() == 0) + moptions.thumbnailFormat = FT_Custom; + else if (cformat->get_active_row_number() == 1) + moptions.thumbnailFormat = FT_Jpeg; + else if (cformat->get_active_row_number() == 2) + moptions.thumbnailFormat = FT_Custom16; + + moptions.maxThumbnailHeight = (int)maxThumbSize->get_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.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(); + + // Sounds + moptions.sndEnable = ckbSndEnable->get_active (); + moptions.sndBatchQueueDone = txtSndBatchQueueDone->get_text (); + moptions.sndLngEditProcDone = txtSndLngEditProcDone->get_text (); + moptions.sndLngEditProcDoneSecs = spbSndLngEditProcDoneSecs->get_value (); +} + +void Preferences::fillPreferences () { + + tconn.block (true); + sconn.block (true); + dfconn.block (true); + ffconn.block (true); + + rprofiles->set_active_text (moptions.defProfRaw); + iprofiles->set_active_text (moptions.defProfImg); + dateformat->set_text (moptions.dateFormat); + panFactor->set_value(moptions.panAccelFactor); + 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); + + 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); + 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.customProfileBuilder); + + 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]; + } + + if (moptions.thumbnailFormat == FT_Custom) + cformat->set_active (0); + else if (moptions.thumbnailFormat == FT_Jpeg) + cformat->set_active (1); + else if (moptions.thumbnailFormat == FT_Custom16) + cformat->set_active (2); + + 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); + + 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); + + //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); + + chOverwriteOutputFile->set_active (moptions.overwriteOutputFile); + + // Sounds + ckbSndEnable->set_active (moptions.sndEnable); + txtSndBatchQueueDone->set_text (moptions.sndBatchQueueDone); + txtSndLngEditProcDone->set_text (moptions.sndLngEditProcDone); + spbSndLngEditProcDoneSecs->set_value (moptions.sndLngEditProcDoneSecs); +} + +/* +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::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); + 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 () { + rprofiles->set_tooltip_text(rprofiles->get_active_text()); +} + +void Preferences::forImageComboChanged () { + iprofiles->set_tooltip_text(iprofiles->get_active_text()); +} + +void Preferences::layoutComboChanged () { + editorLayout->set_tooltip_text(editorLayout->get_active_text()); +} + +void Preferences::cacheFormatComboChanged () { + cformat->set_tooltip_text(cformat->get_active_text()); +} + + +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; +} diff --git a/rtgui/preferences.h b/rtgui/preferences.h new file mode 100644 index 000000000..4047c812c --- /dev/null +++ b/rtgui/preferences.h @@ -0,0 +1,203 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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 { + + 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; + Gtk::ComboBoxText* rprofiles; + Gtk::ComboBoxText* iprofiles; + 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* blinkClipped; + Gtk::SpinButton* hlThresh; + Gtk::SpinButton* shThresh; + + Gtk::SpinButton* panFactor; + + Gtk::ComboBoxText* intent; + + Gtk::ComboBoxText* theme; + Gtk::CheckButton* slimUI; + Gtk::HBox* hbtheme; + Gtk::CheckButton* chUseSystemTheme; + Gtk::FontButton* fontbutton; + Gtk::ColorButton* butCropCol; + + Gtk::ComboBoxText* cformat; + 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::CheckButton* ckbmenuGroupRank; + Gtk::CheckButton* ckbmenuGroupLabel; + Gtk::CheckButton* ckbmenuGroupFileOperations; + Gtk::CheckButton* ckbmenuGroupProfileOperations; + Gtk::CheckButton* ckbmenuGroupExtProg; + + Gtk::CheckButton* chOverwriteOutputFile; + + Gtk::CheckButton* saveParamsFile; + Gtk::CheckButton* saveParamsCache; + 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::CheckButton* ckbHistogramPositionLeft; + Gtk::CheckButton* ckbShowProfileSelector; + Gtk::CheckButton* ckbFileBrowserToolbarSingleRow; + Gtk::CheckButton* ckbHideTPVScrollbar; + Gtk::CheckButton* ckbSquareDetailWindow; + Gtk::CheckButton* ckbUseIconNoText; + + + Options moptions; + sigc::connection tconn, sconn, fconn, usethcon, addc, setc, dfconn, ffconn; + sigc::connection autoMonProfileConn, sndEnableConn, langAutoDetectConn; + 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 cacheFormatComboChanged (); + 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* getSoundPanel (); + + public: + Preferences (RTWindow *rtwindow); + ~Preferences (); + + void savePressed (); + void loadPressed (); + void okPressed (); + void cancelPressed (); + void aboutPressed (); + void autoMonProfileToggled (); + void sndEnableToggled (); + void langAutoDetectToggled (); + + 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 selectICCProfileDir (); +// void selectMonitorProfile (); +}; + +#endif diff --git a/rtgui/preprocess.cc b/rtgui/preprocess.cc new file mode 100644 index 000000000..c6424e5de --- /dev/null +++ b/rtgui/preprocess.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 "preprocess.h" +#include "guiutils.h" +#include "../rtengine/safegtk.h" +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +PreProcess::PreProcess () : Gtk::VBox(), FoldableToolPanel(this) +{ + hotDeadPixel = Gtk::manage(new Gtk::CheckButton((M("TP_PREPROCESS_HOTDEADPIXFILT")))); + + 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..a7d2b2081 --- /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) { + + 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) { + Glib::Mutex::Lock 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_) { + Glib::Mutex::Lock 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..da7bcee88 --- /dev/null +++ b/rtgui/previewhandler.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 _PREVIEWHANDLER_ +#define _PREVIEWHANDLER_ + +#include "../rtengine/rtengine.h" +#include +#include + +class PreviewListener { + + public: + 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; + Glib::Mutex 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..43976cbfd --- /dev/null +++ b/rtgui/previewloader.cc @@ -0,0 +1,175 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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 "../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_; + Glib::Mutex mutex_; + JobSet jobs_; + gint nConcurrentThreads; + + void processNextJob() + { + Job j; + { + Glib::Mutex::Lock 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){} 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 Glib::Mutex smutex_; + Glib::Mutex::Lock 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 ) + { + { + Glib::Mutex::Lock 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); + Glib::Mutex::Lock 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..f1194ba34 --- /dev/null +++ b/rtgui/previewmodepanel.cc @@ -0,0 +1,243 @@ +/* + * This file is part of RawTherapee. + * + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#include "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::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..cc2edd33f --- /dev/null +++ b/rtgui/previewmodepanel.h @@ -0,0 +1,75 @@ +/* + * 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(); + + 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..6465f64c9 --- /dev/null +++ b/rtgui/profilechangelistener.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 _PROFILECHANGELISTENER_ +#define _PROFILECHANGELISTENER_ + +#include "../rtengine/rtengine.h" +#include + +class ProfileChangeListener { + + public: + 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) {} +}; + +#endif + diff --git a/rtgui/profilepanel.cc b/rtgui/profilepanel.cc new file mode 100644 index 000000000..de02e9ae2 --- /dev/null +++ b/rtgui/profilepanel.cc @@ -0,0 +1,484 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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; + +extern Glib::ustring argv0; + +PartialPasteDlg* ProfilePanel::partialProfileDlg; + + +void ProfilePanel::init () { + partialProfileDlg = new PartialPasteDlg("Foo"); +} + +void ProfilePanel::cleanup () { + delete partialProfileDlg; +} + +ProfilePanel::ProfilePanel (bool readOnly) : lastFilename("") { + + tpc = NULL; + + profiles = Gtk::manage (new MyComboBoxText ()); + 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 (*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; + + refreshProfileList (); + + profiles->set_active (0); + old = profiles->get_active_text(); + 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 () { + + if (custom) { custom->deleteInstance(); delete custom; } + if (lastsaved) { lastsaved->deleteInstance(); delete lastsaved; } +} + +void ProfilePanel::refreshProfileList () { + + Glib::ustring oldsel = profiles->get_active_text (); + changeconn.block (true); + + // clear items + profiles->clear_items (); + pparams.clear (); + + // re-parse profile directories (deletes old ones) + profileStore.parseProfiles (); + pparams = profileStore.getProfileNames (); + for (unsigned int i=0; iappend_text (pparams[i]); + + if (custom) + profiles->append_text (Glib::ustring("(") + M("PROFILEPANEL_PCUSTOM") + ")"); + if (lastsaved) + profiles->append_text (Glib::ustring("(") + M("PROFILEPANEL_PLASTSAVED") + ")"); + + profiles->set_active_text (oldsel); + changeconn.block (false); +} + +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 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); + + PartialProfile* toSave = NULL; + if (profiles->get_active_text() == Glib::ustring("(") + M("PROFILEPANEL_PCUSTOM") + ")") + toSave = custom; + else if (profiles->get_active_text() == Glib::ustring("(") + M("PROFILEPANEL_PLASTSAVED") + ")") + toSave = lastsaved; + else + toSave = profileStore.getProfile (profiles->get_active_text()); + + 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); + ppTemp.pparams->save (fname, "", ppTemp.pedited); + ppTemp.deleteInstance(); + } + else { + // saving a full profile + toSave->pparams->save (fname); + } + refreshProfileList (); + } + } + done = true; + } while (!done); + return; +} + +/* + * Copy the actual full profile to the clipboard + */ +void ProfilePanel::copy_clicked (GdkEventButton* event) { + + if (event->button != 1) + return; + + PartialProfile* toSave = NULL; + if (profiles->get_active_text() == Glib::ustring("(") + M("PROFILEPANEL_PCUSTOM") + ")") + toSave = custom; + else if (profiles->get_active_text() == Glib::ustring("(") + M("PROFILEPANEL_PLASTSAVED") + ")") + toSave = lastsaved; + else + toSave = profileStore.getProfile (profiles->get_active_text()); + + // 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 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; + } + int err = custom->load (fname); + if (!err) { + bool prevState = changeconn.block(true); + Glib::ustring newEntry = Glib::ustring("(") + M("PROFILEPANEL_PCUSTOM") + ")"; + profiles->append_text (newEntry); + profiles->set_active_text (newEntry); + old = profiles->get_active_text(); + 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("PROFILEPANEL_PFILE")); + } + else if (customCreated) { + // we delete custom + custom->deleteInstance(); + delete custom; + } + } + 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); + Glib::ustring newEntry = Glib::ustring("(") + M("PROFILEPANEL_PCUSTOM") + ")"; + + if (!custom) { + custom = new PartialProfile (true); + custom->pedited->set(true); + profiles->append_text (newEntry); + } + ProcParams pp = clipboard.getProcParams (); + *custom->pparams = pp; + + profiles->set_active_text (newEntry); + old = profiles->get_active_text(); + + 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 (PartialProfile* newpp, Glib::ustring profname) { + + if (!newpp) + return; + + if (tpc) + tpc->profileChange (newpp, EvProfileChanged, profname); +} + +void ProfilePanel::selection_changed () { + + Glib::ustring entry; + if (profiles->get_active_text() == (entry = Glib::ustring("(") + M("PROFILEPANEL_PCUSTOM") + ")")) { + if (!dontupdate) + changeTo (custom, entry); + } + else if (profiles->get_active_text() == (entry = Glib::ustring("(") + M("PROFILEPANEL_PLASTSAVED") + ")")) + changeTo (lastsaved, entry); + else { + PartialProfile* s = profileStore.getProfile (profiles->get_active_text()); + if (s) + changeTo (s, profiles->get_active_text()); + } + old = profiles->get_active_text (); + 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; + + Glib::ustring entry = Glib::ustring("(") + M("PROFILEPANEL_PCUSTOM") + ")"; + if (profiles->get_active_text() != entry) { + dontupdate = true; + if (!custom) { + custom = new PartialProfile (true); + custom->set(true); + profiles->append_text (entry); + } + profiles->set_active_text (entry); + old = profiles->get_active_text(); + } + *custom->pparams = *p; +} + +void ProfilePanel::initProfile (const Glib::ustring& profname, ProcParams* lastSaved) { + + changeconn.block (true); + + profiles->clear_items (); + pparams.clear (); + + pparams = profileStore.getProfileNames (); + for (unsigned int i=0; iappend_text (pparams[i]); + + 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); + lastsaved = new PartialProfile(lastSaved, pe); + } + + Glib::ustring defline = profname; + PartialProfile* defprofile = profileStore.getProfile (profname); + + if (lastsaved) { + defline = Glib::ustring("(") + M("PROFILEPANEL_PLASTSAVED") + ")"; + defprofile = lastsaved; + profiles->append_text (defline); + } + + if (tpc) { + if (lastsaved) + tpc->setDefaults (lastsaved->pparams); + else + tpc->setDefaults (profileStore.getProfile (profname)->pparams); + } + if (defprofile) { + old = defline; + profiles->set_active_text (defline); + changeconn.block (false); + if (tpc) + tpc->profileChange (defprofile, EvPhotoLoaded, defline); + } + else { + bool dels = false; + // select first valid profile + old = ""; + profiles->set_active (0); + PartialProfile* s = profileStore.getProfile (profiles->get_active_text()); + if (!s) { + changeconn.block (false); + s = new PartialProfile (true); + s->set(true); + dels = true; // we've created a temporary PartialProfile, so we set a flag to destroy it + if (tpc) + tpc->profileChange (s, EvPhotoLoaded, DEFPROFILE_INTERNAL); + } + else { + Glib::ustring cProfile = profiles->get_active_text(); + changeconn.block (false); + if (tpc) + tpc->profileChange (s, EvPhotoLoaded, cProfile); + } + + if (dels) { + s->deleteInstance(); + delete s; + } + } +} + + + diff --git a/rtgui/profilepanel.h b/rtgui/profilepanel.h new file mode 100644 index 000000000..e2bf6cd9c --- /dev/null +++ b/rtgui/profilepanel.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 _PROFILEPANEL_ +#define _PROFILEPANEL_ + +#include +#include +#include "../rtengine/rtengine.h" +#include "pparamschangelistener.h" +#include "profilechangelistener.h" +#include "partialpastedlg.h" +#include "guiutils.h" + +class ProfilePanel : public Gtk::VBox, public PParamsChangeListener { + + private: + + Glib::ustring lastFilename; + + protected: + + static PartialPasteDlg* partialProfileDlg; + Gtk::Button* save; + Gtk::Button* load; + Gtk::Button* copy; + Gtk::Button* paste; + MyComboBoxText* profiles; + std::vector pparams; + rtengine::procparams::PartialProfile* custom; + rtengine::procparams::PartialProfile* lastsaved; + Glib::ustring old; + ProfileChangeListener* tpc; + bool dontupdate; + sigc::connection changeconn; + + void changeTo (rtengine::procparams::PartialProfile* newpp, Glib::ustring profname); + void refreshProfileList (); + + public: + + ProfilePanel (bool readOnly=false); + virtual ~ProfilePanel (); + + void setProfileChangeListener (ProfileChangeListener* ppl) { tpc = ppl; } + + static void init (); + static void cleanup (); + + void initProfile (const Glib::ustring& profname, rtengine::procparams::ProcParams* lastSaved); + void setInitialFileName (const Glib::ustring& filename) {lastFilename = 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 (); +}; + +#endif diff --git a/rtgui/profilestore.cc b/rtgui/profilestore.cc new file mode 100644 index 000000000..bbeba0460 --- /dev/null +++ b/rtgui/profilestore.cc @@ -0,0 +1,208 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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 "../rtengine/safegtk.h" + +ProfileStore profileStore; + +using namespace rtengine; +using namespace rtengine::procparams; + +ProfileStore::ProfileStore () { + storeState = STORESTATE_NOTINITIALIZED; + parseMutex = NULL; +} + +bool ProfileStore::init () { + if (storeState == STORESTATE_DELETED) + return false; + if (storeState == STORESTATE_NOTINITIALIZED) { + storeState = STORESTATE_BEINGINITIALIZED; + parseMutex = new Glib::Mutex(); + _parseProfiles (); + storeState = STORESTATE_INITIALIZED; + } + return true; +} + +ProfileStore::~ProfileStore () { + + // This lock prevent object's suppression while scanning the directories + storeState = STORESTATE_DELETED; + Glib::Mutex::Lock lock(*parseMutex); + + for (std::map::iterator i = partProfiles.begin(); i!=partProfiles.end(); i++) { + if (i->second->pparams) delete i->second->pparams; + if (i->second->pedited) delete i->second->pedited; + delete i->second; + } + partProfiles.clear (); + 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 + */ +void ProfileStore::parseProfiles () { + + if (!init()) + // I don't even know if this situation can occur + return; + Glib::Mutex::Lock lock(*parseMutex); + + _parseProfiles (); +} + +void ProfileStore::_parseProfiles () { + + // clear loaded profiles + for (std::map::iterator i = partProfiles.begin(); i!=partProfiles.end(); i++) { + delete i->second->pparams; + delete i->second->pedited; + delete i->second; + } + partProfiles.clear (); + + parseDir (options.getUserProfilePath()); + parseDir (options.getGlobalProfilePath()); +} + +void ProfileStore::parseDir (const Glib::ustring& pdir) { + + // reload the available profiles from the profile dir + if (pdir!="" && safe_file_test(pdir, Glib::FILE_TEST_EXISTS) && safe_file_test(pdir, Glib::FILE_TEST_IS_DIR)) { + // process directory + Glib::ustring dirname = pdir; + Glib::Dir* dir = NULL; + dir = new Glib::Dir (dirname); + 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, paramFileExtension)) { + if( options.rtSettings.verbose ) + printf ("Processing file %s...\n", fname.c_str()); + Glib::ustring name = sname.substr(0,lastdot); + std::map::iterator j = partProfiles.find(name); + if (j!=partProfiles.end()) { + j->second->deleteInstance(); + delete j->second; + partProfiles.erase (j); + } + PartialProfile* pProf = new PartialProfile (true); + int res = pProf->load (fname); + if (!res && pProf->pparams->ppVersion>=220) { + partProfiles[name] = pProf; + } + else { + pProf->deleteInstance(); + delete pProf; + } + } + } + } + delete dir; + } + // Check if the default profiles has been found. If no, create default instance + // This operation is safe: if the profile is finally found in another directory, the profile will be updated + if (partProfiles.find(options.defProfRaw) == partProfiles.end()) { + PartialProfile* pProf = new PartialProfile (true); + pProf->set(true); + partProfiles[options.defProfRaw] = pProf; + } + if (partProfiles.find(options.defProfImg) == partProfiles.end()) { + PartialProfile* pProf = new PartialProfile (true); + pProf->set(true); + partProfiles[options.defProfImg] = pProf; + } +} + +PartialProfile* ProfileStore::getProfile (const Glib::ustring& profname) { + + if (!init()) + // I don't even know if this situation can occur + return NULL; + Glib::Mutex::Lock lock(*parseMutex); + + if (partProfiles.find(profname) != partProfiles.end()) { + return partProfiles[profname]; + } + else { + return NULL; + } +} + +std::vector ProfileStore::getProfileNames () { + + std::vector ret; + + if (!init()) + // I don't even know if this situation can occur + return ret; + Glib::Mutex::Lock lock(*parseMutex); + + for (std::map::iterator i = partProfiles.begin(); i!=partProfiles.end(); i++) + ret.push_back (i->first); + return ret; +} + +/* + * 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 + */ +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 + + PartialProfile* pProf = getProfile (isRaw ? options.defProfRaw : options.defProfImg); + // NOTE: pProf should not be NULL anymore, since init() should have created the default profiles already + 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 + */ +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 + + PartialProfile* pProf = getProfile (isRaw ? options.defProfRaw : options.defProfImg); + // NOTE: pProf should not be NULL anymore, since init() should have created the default profiles already + return pProf; +} + diff --git a/rtgui/profilestore.h b/rtgui/profilestore.h new file mode 100644 index 000000000..40d3def30 --- /dev/null +++ b/rtgui/profilestore.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 _PROFILESTORE_ +#define _PROFILESTORE_ + +#include +#include +#include "../rtengine/rtengine.h" +#include "paramsedited.h" +#include + +class ProfileStore { + + typedef enum { + STORESTATE_NOTINITIALIZED, + STORESTATE_BEINGINITIALIZED, + STORESTATE_INITIALIZED, + STORESTATE_DELETED + } StoreState; + + Glib::Mutex *parseMutex; + StoreState storeState; + std::map partProfiles; + void parseDir (const Glib::ustring& pdir); + void _parseProfiles (); + + public: + + ProfileStore(); + ~ProfileStore(); + bool init (); + void parseProfiles (); + rtengine::procparams::PartialProfile* getProfile (const Glib::ustring& profname); + std::vector getProfileNames (); + rtengine::procparams::ProcParams* getDefaultProcParams (bool isRaw); + rtengine::procparams::PartialProfile* getDefaultPartialProfile (bool isRaw); +}; + +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..ea942336d --- /dev/null +++ b/rtgui/rawcacorrection.cc @@ -0,0 +1,171 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#include "rawcacorrection.h" +#include "guiutils.h" +#include "../rtengine/safegtk.h" +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +RAWCACorr::RAWCACorr () : Gtk::VBox(), FoldableToolPanel(this) +{ + 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)); + 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)); + 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..91b31dcf4 --- /dev/null +++ b/rtgui/rawexposure.cc @@ -0,0 +1,231 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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) +{ + 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..e0b83b1d8 --- /dev/null +++ b/rtgui/rawprocess.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 "rawprocess.h" +#include "options.h" +#include "guiutils.h" +using namespace rtengine; +using namespace rtengine::procparams; + +RawProcess::RawProcess () : Gtk::VBox(), FoldableToolPanel(this) +{ + Gtk::HBox* hb1 = Gtk::manage (new Gtk::HBox ()); + hb1->pack_start (*Gtk::manage (new Gtk::Label ( M("TP_RAW_DMETHOD") +": ")),Gtk::PACK_SHRINK, 4); + dmethod = Gtk::manage (new MyComboBoxText ()); + for( size_t i=0; i< procparams::RAWParams::numMethods;i++) + dmethod->append_text(procparams::RAWParams::methodstring[i]); + + dmethod->set_active(0); + 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); + pack_start( *Gtk::manage( new Gtk::HSeparator()), Gtk::PACK_SHRINK, 4 ); + + ccOptions = Gtk::manage (new Gtk::VBox ()); + ccOptions->set_border_width(4); + 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; + } + //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]) + dcbOptions->show(); + else + dcbOptions->hide(); + + 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]) + ccOptions->show(); + else + ccOptions->hide(); + + lastDCBen = pp->raw.dcb_enhance; + //lastALLen = pp->raw.all_enhance; + + 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); + + if( !pedited->raw.dmethod ) + dmethod->set_active(procparams::RAWParams::numMethods); // No name + } + + 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(); + + 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(); + + } +} + +void RawProcess::setBatchMode(bool batchMode) +{ + dmethod->set_active(procparams::RAWParams::numMethods); // No name + dcbOptions->hide(); + ToolPanel::setBatchMode (batchMode); + ccSteps->showEditedCB (); + dcbIterations->showEditedCB (); +} + +void RawProcess::setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited) +{ + dcbIterations->setDefault( defParams->raw.dcb_iterations); + ccSteps->setDefault (defParams->raw.ccSteps); + if (pedited) { + dcbIterations->setDefaultEditedState( pedited->raw.dcbIterations ? Edited : UnEdited); + ccSteps->setDefaultEditedState(pedited->raw.ccSteps ? Edited : UnEdited); + }else{ + dcbIterations->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() ); + } +} + +void RawProcess::methodChanged () +{ + int curSelection = dmethod->get_active_row_number(); + if ( curSelection == procparams::RAWParams::dcb){ + dcbOptions->show(); + }else{ + dcbOptions->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..817674cbe --- /dev/null +++ b/rtgui/rawprocess.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 _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; + Gtk::VBox *ccOptions; + Adjuster* dcbIterations; + Gtk::CheckButton* dcbEnhance; + //Gtk::VBox *allOptions; + //Gtk::CheckButton* allEnhance; + + 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..c48ac032b --- /dev/null +++ b/rtgui/resize.cc @@ -0,0 +1,574 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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) { + + 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..c9a4645e2 --- /dev/null +++ b/rtgui/rgbcurves.cc @@ -0,0 +1,128 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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) { + + 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); + } + + 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 (); + + if (pedited) { + pedited->rgbCurves.rcurve = !Rshape->isUnChanged (); + pedited->rgbCurves.gcurve = !Gshape->isUnChanged (); + pedited->rgbCurves.bcurve = !Bshape->isUnChanged (); + } +} + + +/* + * Curve listener + * + * If more than one curve has been added, the curve listener is automatically + * set to 'multi=true', and send a pointer of the modified curve in a parameter + */ +void 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::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + curveEditorG->setBatchMode (batchMode); +} + + +void RGBCurves::updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, 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..316c5e4d1 --- /dev/null +++ b/rtgui/rgbcurves.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 _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; + + 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 & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma); +}; + +#endif diff --git a/rtgui/rotate.cc b/rtgui/rotate.cc new file mode 100644 index 000000000..30ca9b0f9 --- /dev/null +++ b/rtgui/rotate.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 "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) { + + rlistener = NULL; + + degree = Gtk::manage (new Adjuster (M("TP_ROTATE_DEGREE"), -45, 45, 0.01, 0)); + 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..80bd00cb1 --- /dev/null +++ b/rtgui/rtimage.cc @@ -0,0 +1,136 @@ +/* + * 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..fdf9f3d73 --- /dev/null +++ b/rtgui/rtwindow.cc @@ -0,0 +1,618 @@ +/* + * 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" + +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 + + 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(); + + 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; +} + +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(); + + 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; + + 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 false; + } + 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) { + // 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(); + + 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(); + return true; +} + +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..b798613f9 --- /dev/null +++ b/rtgui/rtwindow.h @@ -0,0 +1,94 @@ +/* + * 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" + +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; + 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); + + public: + RTWindow (); + ~RTWindow(); + + 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..e5eccb67a --- /dev/null +++ b/rtgui/saveasdlg.cc @@ -0,0 +1,221 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#include "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); + +// Unique filename option +// ~~~~~~~~~~~~~~~~~~~~~~ + autoSuffix = Gtk::manage( new Gtk::CheckButton (M("SAVEDLG_AUTOSUFFIX")) ); + autoSuffix->set_active(options.autoSuffix); + +// 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); + +// 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->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 (*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 (); + +} + +bool SaveAsDialog::getAutoSuffix () { + + return autoSuffix->get_active(); +} + +bool SaveAsDialog::getImmediately () { + + return saveMethod[0]->get_active (); +} + +bool SaveAsDialog::getToHeadOfQueue () { + + return saveMethod[1]->get_active (); +} + +bool SaveAsDialog::getToTailOfQueue () { + + return saveMethod[2]->get_active (); +} + +int SaveAsDialog::getSaveMethodNum () { + 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); +} diff --git a/rtgui/saveasdlg.h b/rtgui/saveasdlg.h new file mode 100644 index 000000000..1570a95ab --- /dev/null +++ b/rtgui/saveasdlg.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 _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; + 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 + */ + + public: + SaveAsDialog (Glib::ustring initialDir); + + Glib::ustring getFileName (); + Glib::ustring getDirectory (); + SaveFormat getFormat (); + bool getAutoSuffix (); + bool getImmediately (); + bool getToHeadOfQueue (); + bool getToTailOfQueue (); + int getSaveMethodNum (); + + void setInitialFileName (Glib::ustring iname); + + void okPressed (); + void cancelPressed (); + void formatChanged (Glib::ustring f); +}; + + +#endif diff --git a/rtgui/saveformatpanel.cc b/rtgui/saveformatpanel.cc new file mode 100644 index 000000000..9d906e66f --- /dev/null +++ b/rtgui/saveformatpanel.cc @@ -0,0 +1,173 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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) { + + formatChanged (); +} 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..3d6966780 --- /dev/null +++ b/rtgui/shadowshighlights.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 "shadowshighlights.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +ShadowsHighlights::ShadowsHighlights () : Gtk::VBox(), FoldableToolPanel(this) { + + 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("GENERAL_HIGH_QUALITY"))); + 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, 10)); + 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, 10)); + 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..5f8d3387b --- /dev/null +++ b/rtgui/sharpenedge.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 "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) { + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); + enabled->set_active (true); + pack_start(*enabled, Gtk::PACK_SHRINK, 0); + + 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..ee8328426 --- /dev/null +++ b/rtgui/sharpening.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 "sharpening.h" +#include +#include +#include "guiutils.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +Sharpening::Sharpening () : Gtk::VBox(), FoldableToolPanel(this) { + + 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_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, 125)); + 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 (!pedited->sharpening.enabled); + halocontrol->set_inconsistent (!pedited->sharpening.halocontrol); + edgesonly->set_inconsistent (!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 && 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 && enabled->get_active()) { + listener->panelChanged (EvShrThresh, threshold->getHistoryString()); + } +} + +void Sharpening::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 (EvShrEnabled, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvShrEnabled, M("GENERAL_DISABLED")); + } +} + +void Sharpening::edgesonly_toggled () { + + if (batchMode) { + 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 && enabled->get_active()) { + if (edgesonly->get_active ()) + listener->panelChanged (EvShrEdgeOnly, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvShrEdgeOnly, M("GENERAL_DISABLED")); + } +} + +void Sharpening::halocontrol_toggled () { + + if (batchMode) { + 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 && enabled->get_active()) { + 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 && 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..ccab3a638 --- /dev/null +++ b/rtgui/sharpenmicro.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 "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) { + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); + enabled->set_active (true); + pack_start(*enabled, Gtk::PACK_SHRINK, 0); + enabled->show (); + + 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..67be7a5e9 --- /dev/null +++ b/rtgui/soundman.cc @@ -0,0 +1,68 @@ +/* +* 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 + + +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 ); +#else + // TODO: Add code for other OSes here + printf("Sound not supported on your OS (yet)\n"); +#endif +} \ No newline at end of file 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..d77d4002a --- /dev/null +++ b/rtgui/splash.cc @@ -0,0 +1,251 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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); + + // 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)); +} diff --git a/rtgui/splash.h b/rtgui/splash.h new file mode 100644 index 000000000..15ffbe000 --- /dev/null +++ b/rtgui/splash.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 __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); +}; + +#endif 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..fa8d5f7d1 --- /dev/null +++ b/rtgui/thumbbrowserbase.cc @@ -0,0 +1,625 @@ +/* + * 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) { + 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 () { + 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 (); +// gdk_window_process_updates (get_window()->gobj(), true); + } +} + +void ThumbBrowserBase::scroll (int direction) { + 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) { + 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()); +} + +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 () { + + 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 () { + // TODO: Check for Linux + #ifdef WIN32 + Glib::RWLock::ReaderLock l(entryRW); + #endif + + 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) { + + 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; + } + resizeThumbnailArea (currx, numOfRows*rowHeight); + } + else { + int availWidth = internal.get_width(); + // initial number of columns + int 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; + } + resizeThumbnailArea (colsWidth, curry); + } +} + + +void ThumbBrowserBase::Internal::on_realize() +{ + 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) { + Glib::ustring ttip = ""; + 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_text (ttip); + return true; + } + else + return false; +} + +void ThumbBrowserBase::styleChanged (const Glib::RefPtr& style) { + + 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) { + return parent->keyPressed (event); +} + +bool ThumbBrowserBase::Internal::on_button_press_event (GdkEventButton* event) { + 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) { + ThumbBrowserEntryBase* fileDescr = NULL; + bool handled = false; + + { + 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 (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; + 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]); + } + } + 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; + selectionChanged (); + } + else { + for (size_t i=0; iselected = false; + selected.clear (); + if (fileDescr) { + selected.push_back (fileDescr); + fileDescr->selected = true; + } + lastClicked = fileDescr; + 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; + selectionChanged (); + } + rightClicked (fileDescr); + } +} + +bool ThumbBrowserBase::Internal::on_expose_event(GdkEventExpose* event) { + // TODO: Check for Linux + #ifdef WIN32 + Glib::RWLock::ReaderLock l(parent->entryRW); + #endif + + 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()); + 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) { + int w = get_width(); + int h = get_height(); + + for (size_t i=0; ifd.size(); i++) + if (parent->fd[i]->drawable && parent->fd[i]->insideWindow (0, 0, w, h)) { + parent->fd[i]->releaseNotify (event->button, event->type, event->state, (int)event->x, (int)event->y); + } + return true; +} + +bool ThumbBrowserBase::Internal::on_motion_notify_event (GdkEventMotion* event) { + int w = get_width(); + int h = get_height(); + + for (size_t i=0; ifd.size(); i++) + if (parent->fd[i]->drawable && parent->fd[i]->insideWindow (0, 0, w, h)) { + #ifdef WIN32 + //l.release(); // 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) { + + parent->scroll (event->direction); + return true; +} + + +void ThumbBrowserBase::redraw () { + + arrangeFiles (); + queue_draw (); +} + +void ThumbBrowserBase::zoomChanged (bool zoomIn) { + + int newHeight=0; + int optThumbSize=getCurrentThumbSize(); + 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; + if (inTabMode) options.thumbSizeTab = newHeight; else options.thumbSize = newHeight; + + { + // TODO: Check for Linux + #ifdef WIN32 + Glib::RWLock::WriterLock l(entryRW); + #endif + + for (size_t i=0; iresize (previewHeight); + } + + redraw (); +#ifdef WIN32 + gdk_window_process_updates (get_window()->gobj(), true); +#endif +} + +int ThumbBrowserBase::getCurrentThumbSize() { return inTabMode ? options.thumbSizeTab : options.thumbSize; } + +void ThumbBrowserBase::refreshThumbImages () { + { + // TODO: Check for Linux + #ifdef WIN32 + Glib::RWLock::WriterLock l(entryRW); + #endif + + int previewHeight = getCurrentThumbSize(); + for (size_t i=0; iresize (previewHeight); + } + + redraw (); +} + +void ThumbBrowserBase::refreshQuickThumbImages () { + // TODO: Check for Linux + #ifdef WIN32 + Glib::RWLock::WriterLock l(entryRW); + #endif + + for (size_t i=0; irefreshQuickThumbnailImage (); +} + +void ThumbBrowserBase::refreshEditedState (const std::set& efiles) { + + editedFiles = efiles; + 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.thumbSizeTab!=options.thumbSize) { + // TODO: Check for Linux + #ifdef WIN32 + Glib::RWLock::WriterLock l(entryRW); + #endif + + for (size_t i=0; iresize (getCurrentThumbSize()); + } + + redraw (); + + // Scroll to selected position if going into ribbon mode or back + // Tab mode is horizontal, file browser is vertical + if (!selected.empty()) { + if (inTabMode) { + double h=selected[0]->getStartX(); + hscroll.set_value (min(h, hscroll.get_adjustment()->get_upper())); + } else { + double v=selected[0]->getStartY(); + 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 + + // 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) { + + 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..90164596a --- /dev/null +++ b/rtgui/thumbbrowserbase.h @@ -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 . + */ +#ifndef _THUMBNAILBROWSERBASE_ +#define _THUMBNAILBROWSERBASE_ + +#include +#include "thumbbrowserentrybase.h" +#include +#include "options.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 + + Internal internal; + Gtk::HScrollbar hscroll; + Gtk::VScrollbar vscroll; + + int inW, inH; + + bool inTabMode; // Tab mode has e.g. different preview heights + int getCurrentThumbSize(); // depending on filmstrip/file browser mode + + 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); + + protected: + + int eventTime; + + Glib::RWLock entryRW; // Locks access to following vectors + std::vector fd; + std::vector selected; + ThumbBrowserEntryBase* lastClicked; + + int previewHeight; + + 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..bbbd79a60 --- /dev/null +++ b/rtgui/thumbbrowserentrybase.cc @@ -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 . + */ +#include "thumbbrowserentrybase.h" +#include "thumbbrowserbase.h" +#include "options.h" +#include "../rtengine/mytime.h" + +ThumbBrowserEntryBase::ThumbBrowserEntryBase (const Glib::ustring& fname) + : preh(0), preview(NULL), buttonSet(NULL), exp_width(0), exp_height(0), redrawRequests(0), + parent(NULL), filename(fname), exifline(""), datetimeline(""), selected(false), + drawable(false),framed(false), processing(false), italicstyle(false), + updatepriority(false) { + + shortname = Glib::path_get_basename (fname); + dispname = shortname; + + upperMargin = 6; + borderWidth = 1; + sideMargin = 8; + lowerMargin = 8; + textGap = 6; + + ofsX = ofsY = 0; +} + +ThumbBrowserEntryBase::~ThumbBrowserEntryBase () { + + delete [] preview; + delete buttonSet; +} + +void ThumbBrowserEntryBase::addButtonSet (LWButtonSet* bs) { + + buttonSet = bs; +} + +void ThumbBrowserEntryBase::updateBackBuffer () { + + if (!parent) + return; + + Gtk::Widget* w = parent->getDrawingArea (); + + backBuffer = Gdk::Pixmap::create (w->get_window(), 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) { + Glib::RWLock::WriterLock l(lockRW); + + 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; + + Glib::RWLock::ReaderLock l(lockRW); // No resizes, position moves etc. inbetween + + 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); + buttonSet->redraw (w->get_window()->create_cairo_context()); + } +} + +void ThumbBrowserEntryBase::setPosition (int x, int y, int w, int h) { + Glib::RWLock::WriterLock l(lockRW); + + 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) { + Glib::RWLock::WriterLock l(lockRW); + + 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..27971475a --- /dev/null +++ b/rtgui/thumbbrowserentrybase.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 _THUMBNAILBROWSERENTRYBASE_ +#define _THUMBNAILBROWSERENTRYBASE_ + +#include +#include "lwbuttonset.h" +#include "thumbnail.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; + + + Glib::RWLock 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 getEffectiveHeight () const { return exp_height; } + int getPreviewHeight () const { return preh; } + int getStartX () const { return startx; } + int getStartY () const { return 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); + Glib::ustring getToolTip (int x, int y); +}; + +#endif diff --git a/rtgui/thumbimageupdater.cc b/rtgui/thumbimageupdater.cc new file mode 100644 index 000000000..096cc8044 --- /dev/null +++ b/rtgui/thumbimageupdater.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 . + */ + +#include +#include "thumbimageupdater.h" +#include +#include "guiutils.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), + 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_; + + Glib::Mutex mutex_; + + JobList jobs_; + + unsigned int active_; + + bool inactive_waiting_; + + Glib::Cond inactive_; + + void + processNextJob(void) + { + Job j; + + { + Glib::Mutex::Lock lock(mutex_); + + // 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",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); + } + + { + Glib::Mutex::Lock lock(mutex_); + + 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; + } + + Glib::Mutex::Lock lock(impl_->mutex_); + + // 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->getFileName().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",t->getFileName().c_str()); + impl_->jobs_.push_back(Impl::Job(tbe,priority,upgrade,l)); + + DEBUG("adding run request %s",t->getFileName().c_str()); + impl_->threadPool_->push(sigc::mem_fun(*impl_, &ThumbImageUpdater::Impl::processNextJob)); +} + + +void +ThumbImageUpdater::removeJobs(ThumbImageUpdateListener* listener) +{ + DEBUG("removeJobs(%p)",listener); + + Glib::Mutex::Lock lock(impl_->mutex_); + + 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"); + + + Glib::Mutex::Lock lock(impl_->mutex_); + + 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..517d44dc4 --- /dev/null +++ b/rtgui/thumbnail.cc @@ -0,0 +1,821 @@ +/* + * 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) { + + cfs.load (getCacheFileName ("data")+".txt"); + loadProcParams (); + _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; + _generateThumbnailImage (); + loadProcParams (); + 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") { + tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, 1, infoFromImage (fname)); + if (tpp) + cfs.format = FT_Jpeg; + } + else if (ext.lowercase()=="png") { + tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, 1); + if (tpp) + cfs.format = FT_Png; + } + else if (ext.lowercase()=="tif" || ext.lowercase()=="tiff") { + tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, 1, infoFromImage (fname)); + 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, TRUE); + } + if (tpp) { + cfs.format = FT_Raw; + cfs.thumbImgType = quick ? CacheImageData::QUICK_THUMBNAIL : CacheImageData::FULL_THUMBNAIL; + infoFromImage (fname, &ri); + } + } + + if (tpp) + { + _saveThumbnail (); + cfs.supported = true; + needsReProcessing = true; + + cfs.save (getCacheFileName ("data")+".txt"); + + generateExifDateTimeStrings (); + } +} + +bool Thumbnail::isSupported () { + return cfs.supported; +} + +const ProcParams& Thumbnail::getProcParams () { + // TODO: Check for Linux + #ifdef WIN32 + Glib::Mutex::Lock lock(mutex); + #endif + + 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.temperature = ct; + } + } + return pparams; // there is no valid pp to return, but we have to return something +} + +/* + * 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) + */ +rtengine::procparams::ProcParams* Thumbnail::createProcParamsForUpdate(bool returnParams, bool forceCPB) { + // 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.customProfileBuilder.empty() && !defaultPparamsPath.empty() && (!hasProcParams() || forceCPB) && cfs && cfs->exifValid) { + // For the filename etc. do NOT use streams, since they are not UTF8 safe + Glib::ustring cmdLine=Glib::ustring("\"") + options.customProfileBuilder + Glib::ustring("\" \"") + fname + Glib::ustring("\" \"") + + Glib::build_filename(defaultPparamsPath, defProf + paramFileExtension) + Glib::ustring("\" "); + + // ustring doesn't know int etc formatting, so take these via (unsafe) stream + std::ostringstream strm; + strm << cfs->fnumber << Glib::ustring(" ") << cfs->shutter << Glib::ustring(" "); + strm << cfs->focalLen << Glib::ustring(" ") << cfs->iso << Glib::ustring(" \""); + strm << cfs->lens << Glib::ustring("\" \"") << cfs->camera << Glib::ustring("\""); + + bool success = safe_spawn_command_line_sync (cmdLine + strm.str()); + + // Now they SHOULD be there (and potentially "partial"), so try to load them and store it as a full procparam + if (success) loadProcParams(); + } + + 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 () { + // TODO: Check for Linux + #ifdef WIN32 + Glib::Mutex::Lock lock(mutex); + #endif + + pparamsValid = false; + pparams.setDefaults(); + 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. */ + + // TODO: Check for Linux + #ifdef WIN32 + Glib::Mutex::Lock lock(mutex); + #endif + + // 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_); + } + + 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) { + // TODO: Check for Linux + #ifdef WIN32 + Glib::Mutex::Lock lock(mutex); + #endif + + 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) { + // coarse.rotate works in ADD mode only, so we set it to 0 first + if (pe->coarse.rotate) + pparams.coarse.rotate = 0; + pe->combine(pparams, pp, true); + } + else pparams = pp; + pparamsValid = true; + needsReProcessing = true; + + setRank(rank); + setColorLabel(colorlabel); + setStage(inTrash); + + if (updateCacheNow) + updateCache (); + + 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 () +{ + Glib::Mutex::Lock lock(mutex); + ++ref; +} + +void Thumbnail::decreaseRef () +{ + { + Glib::Mutex::Lock lock(mutex); + if ( ref == 0 ) + { + return; + } + if ( --ref != 0 ) + { + return; + } + } + cachemgr->closeThumbnail (this); +} + +void Thumbnail::getThumbnailSize (int &w, int &h) { + // TODO: Check for Linux + #ifdef WIN32 + Glib::Mutex::Lock lock(mutex); + #endif + + w=0; + if (!initial_ && tpp) w = tpp->getImageWidth (getProcParams(), h, imgRatio); // this might return 0 if image was just building + if (w==0) { + 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) { + // TODO: Check for Linux + #ifdef WIN32 + Glib::Mutex::Lock lock(mutex); + #endif + + // 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) { + + Glib::Mutex::Lock 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.camera, cfs.focalLen, cfs.focalLen35mm, cfs.focusDist, 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) { + + Glib::Mutex::Lock 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.camera, cfs.focalLen, cfs.focalLen35mm, cfs.focusDist, 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, 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.camera = idata->getCamera(); + + 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.camera = "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; +} + +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"); + + // 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 (); + + } + + getThumbnailSize(tw,th); +} + +void Thumbnail::loadThumbnail (bool firstTrial) { + Glib::Mutex::Lock lock(mutex); + _loadThumbnail(firstTrial); +} + +void Thumbnail::_saveThumbnail () { + + if (!tpp) + return; + + safe_g_remove (getCacheFileName ("images")+".cust"); + safe_g_remove (getCacheFileName ("images")+".cust16"); + safe_g_remove (getCacheFileName ("images")+".jpg"); + + // save thumbnail image + if (options.thumbnailFormat == FT_Custom) + tpp->writeImage (getCacheFileName ("images")+".cust", 1); + else if (options.thumbnailFormat == FT_Custom16) + tpp->writeImage (getCacheFileName ("images")+".cust16", 2); + else if (options.thumbnailFormat == FT_Jpeg) + tpp->writeImage (getCacheFileName ("images")+".jpg", 3); + + // save aehistogram + tpp->writeAEHistogram (getCacheFileName ("aehistograms")); + + // save embedded profile + tpp->writeEmbProfile (getCacheFileName ("embprofiles")+".icc"); + + // save supplementary data + tpp->writeData (getCacheFileName ("data")+".txt"); +} + +void Thumbnail::saveThumbnail () +{ + Glib::Mutex::Lock lock(mutex); + _saveThumbnail(); +} + +void Thumbnail::updateCache (bool updatePParams, bool updateCacheImageData) { + + if (updatePParams && pparamsValid) { + pparams.save ( + options.saveParamsCache ? getCacheFileName ("profiles")+paramFileExtension : "", + options.saveParamsFile ? fname + paramFileExtension : "" + ); + } + if (updateCacheImageData) + cfs.save (getCacheFileName ("data")+".txt"); +} + +Thumbnail::~Thumbnail () { + // TODO: Check for Linux + #ifdef WIN32 + Glib::Mutex::Lock lock(mutex); + #endif + + delete [] lastImg; + delete tpp; +} + +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) +{ + Glib::Mutex::Lock 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..63c3422a6 --- /dev/null +++ b/rtgui/thumbnail.h @@ -0,0 +1,149 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#ifndef _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" + +class CacheManager; +class Thumbnail { + + Glib::Mutex 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 (); + + // Use this to create params on demand for update + rtengine::procparams::ProcParams* createProcParamsForUpdate (bool returnParams, bool forceCPB); + + 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); + 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); } + void getAutoWB (double& temp, double& green) { if (tpp) tpp->getAutoWB (temp, green); } + void getSpotWB (int x, int y, int rect, double& temp, double& green) { if (tpp) tpp->getSpotWB (getProcParams(), x, y, rect, temp, green); } + 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..636f0dada --- /dev/null +++ b/rtgui/tonecurve.cc @@ -0,0 +1,580 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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) { + + 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.9999); + sclip->set_increments (0.001, 0.01); + sclip->set_value (0.002); + sclip->set_digits (4); + 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); + + pack_start (*Gtk::manage (new Gtk::HSeparator())); + +//----------- Exposure Compensation ------------------------ + expcomp = Gtk::manage (new Adjuster (M("TP_EXPOSURE_EXPCOMP"), -5, 10, 0.05, 0)); + pack_start (*expcomp); + hlcompr = Gtk::manage (new Adjuster (M("TP_EXPOSURE_COMPRHIGHLIGHTS"), 0, 500, 1, 70)); + pack_start (*hlcompr); + hlcomprthresh = Gtk::manage (new Adjuster (M("TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD"), 0, 100, 1, 0)); + pack_start (*hlcomprthresh); + +//----------- Black Level ---------------------------------- + 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_FILMLIKE")); + toneCurveMode->append_text (M("TP_EXPOSURE_TCMODE_SATANDVALBLENDING")); + toneCurveMode->append_text (M("TP_EXPOSURE_TCMODE_WEIGHTEDSTD")); + 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_FILMLIKE")); + toneCurveMode2->append_text (M("TP_EXPOSURE_TCMODE_SATANDVALBLENDING")); + toneCurveMode2->append_text (M("TP_EXPOSURE_TCMODE_WEIGHTEDSTD")); + 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); + } + } + + 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_FILMLIKE; + else if (tcMode == 2) pp->toneCurve.curveMode = ToneCurveParams::TC_MODE_SATANDVALBLENDING; + else if (tcMode == 3) pp->toneCurve.curveMode = ToneCurveParams::TC_MODE_WEIGHTEDSTD; + + 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_FILMLIKE; + else if (tcMode == 2) pp->toneCurve.curveMode2 = ToneCurveParams::TC_MODE_SATANDVALBLENDING; + else if (tcMode == 3) pp->toneCurve.curveMode2 = ToneCurveParams::TC_MODE_WEIGHTEDSTD; + + + 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; + } +} + +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 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); + 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); +} + +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) { + + nextBlack = black; + nextExpcomp = expcomp; + nextBrightness = bright; + nextContrast = contr; + nextHlcompr = hlcompr; + nextHlcomprthresh = hlcomprthresh; + g_idle_add (autoExpChangedUI, this); + +// Glib::signal_idle().connect (sigc::mem_fun(*this, &ToneCurve::autoExpComputed_)); +} + +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); +} + +bool ToneCurve::autoExpComputed_ () { + + disableListener (); + enableAll (); + expcomp->setValue (nextExpcomp); + brightness->setValue (nextBrightness); + contrast->setValue (nextContrast); + black->setValue (nextBlack); + hlcompr->setValue (nextHlcompr); + hlcomprthresh->setValue (nextHlcomprthresh); + 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) { + + 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 & 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..bd0e8649a --- /dev/null +++ b/rtgui/tonecurve.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 _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: + Gtk::HBox* abox; + 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; + + 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 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 & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma); +}; + +#endif diff --git a/rtgui/toolbar.cc b/rtgui/toolbar.cc new file mode 100644 index 000000000..99835e2ef --- /dev/null +++ b/rtgui/toolbar.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 "toolbar.h" +#include "multilangmgr.h" +#include "rtimage.h" + +extern Glib::ustring argv0; + +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); + wbConn.block (true); + straConn.block (true); + + handTool->set_active (false); + 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) + 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); + wbConn.block (false); + straConn.block (false); +} + +void ToolBar::hand_pressed () { + + handConn.block (true); + cropConn.block (true); + wbConn.block (true); + straConn.block (true); + if (current!=TMHand) { + wbTool->set_active (false); + cropTool->set_active (false); + straTool->set_active (false); + current = TMHand; + } + handTool->set_active (true); + handConn.block (false); + cropConn.block (false); + wbConn.block (false); + straConn.block (false); + + if (listener) + listener->toolSelected (TMHand); +} + +void ToolBar::wb_pressed () { + + handConn.block (true); + cropConn.block (true); + wbConn.block (true); + straConn.block (true); + if (current!=TMSpotWB) { + handTool->set_active (false); + cropTool->set_active (false); + straTool->set_active (false); + current = TMSpotWB; + } + wbTool->set_active (true); + handConn.block (false); + cropConn.block (false); + wbConn.block (false); + straConn.block (false); + + if (listener) + listener->toolSelected (TMSpotWB); +} + +void ToolBar::crop_pressed () { + + handConn.block (true); + cropConn.block (true); + wbConn.block (true); + straConn.block (true); + if (current!=TMCropSelect) { + handTool->set_active (false); + 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); + wbConn.block (true); + straConn.block (true); + if (current!=TMStraighten) { + handTool->set_active (false); + wbTool->set_active (false); + cropTool->set_active (false); + current = TMStraighten; + } + straTool->set_active (true); + handConn.block (false); + cropConn.block (false); + 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; +} + diff --git a/rtgui/toolbar.h b/rtgui/toolbar.h new file mode 100644 index 000000000..e6c845552 --- /dev/null +++ b/rtgui/toolbar.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 __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); +}; + +#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..93f0022e3 --- /dev/null +++ b/rtgui/toolpanel.cc @@ -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 . + */ +#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); + } +} diff --git a/rtgui/toolpanel.h b/rtgui/toolpanel.h new file mode 100644 index 000000000..ad268b074 --- /dev/null +++ b/rtgui/toolpanel.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 __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; + + public: + + ToolPanel () : listener(NULL), tmp(NULL), batchMode(false) {} + virtual ~ToolPanel() {} + + void setParent (Gtk::Box* parent) {} + Gtk::Box* getParent () { return NULL; } + 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 () {} + + void disableListener () { if (tmp==NULL) tmp = listener; listener = NULL; } + 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) { exp->set_label(Glib::ustring("") + label + Glib::ustring("")); } +}; + +#endif diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc new file mode 100644 index 000000000..cec48dd0e --- /dev/null +++ b/rtgui/toolpanelcoord.cc @@ -0,0 +1,624 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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 ()); + whitebalance = Gtk::manage (new WhiteBalance ()); + vignetting = Gtk::manage (new Vignetting ()); + perspective = Gtk::manage (new PerspCorrection ()); + cacorrection = Gtk::manage (new CACorrection ()); + hlrecovery = Gtk::manage (new HLRecovery ()); + chmixer = Gtk::manage (new ChMixer ()); + 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 (exposurePanel, hlrecovery, M("TP_HLREC_LABEL")); toolPanels.push_back (hlrecovery); + addPanel (colorPanel, vibrance, M("TP_VIBRANCE_LABEL")); toolPanels.push_back (vibrance); + addPanel (colorPanel, chmixer, M("TP_CHMIXER_LABEL")); toolPanels.push_back (chmixer); + addPanel (exposurePanel, shadowshighlights, M("TP_SHADOWSHLIGHTS_LABEL")); toolPanels.push_back (shadowshighlights); + addPanel (detailsPanel, sharpening, M("TP_SHARPENING_LABEL")); toolPanels.push_back (sharpening); + addPanel (detailsPanel, sharpenEdge, M("TP_SHARPENEDGE_LABEL")); toolPanels.push_back (sharpenEdge); + addPanel (detailsPanel, sharpenMicro, M("TP_SHARPENMICRO_LABEL")); 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, lcurve, M("TP_LABCURVE_LABEL")); toolPanels.push_back (lcurve); + addPanel (detailsPanel, impulsedenoise, M("TP_IMPULSEDENOISE_LABEL")); toolPanels.push_back (impulsedenoise); + addPanel (detailsPanel, dirpyrdenoise, M("TP_DIRPYRDENOISE_LABEL")); toolPanels.push_back (dirpyrdenoise); + addPanel (detailsPanel, defringe, M("TP_DEFRINGE_LABEL")); toolPanels.push_back (defringe); + addPanel (detailsPanel, dirpyrequalizer, M("TP_DIRPYREQUALIZER_LABEL")); 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")); toolPanels.push_back (rawprocess); + addPanel (rawPanel, preprocess, M("TP_PREPROCESS_LABEL")); 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) { + + 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(label); + + 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->setSizeListener (crop); + ipc->setSizeListener (resize); + } + + icm->setRawMeta (raw, (const rtengine::ImageData*)pMetaData); + lensProf->setRawMeta (raw, pMetaData); + + hlrecovery->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[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); + if (x>0 && y>0) { + double temp; + double green; + ipc->getSpotWB (x, y, whitebalance->getSize (), 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 & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma) { + + toneCurve->updateCurveBackgroundHistogram (histToneCurve, histLCurve, histRed, histGreen, histBlue, histLuma); + rgbcurves->updateCurveBackgroundHistogram(histToneCurve, histLCurve,histRed,histGreen, histBlue, histLuma); + lcurve->updateCurveBackgroundHistogram (histToneCurve, histLCurve, 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) { + 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) { + 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) { + 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; + } +} diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h new file mode 100644 index 000000000..e3ed8c263 --- /dev/null +++ b/rtgui/toolpanelcoord.h @@ -0,0 +1,243 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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 "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 "hlrec.h" +#include "cacorrection.h" +#include "lensprofile.h" +#include "distortion.h" +#include "perspective.h" +#include "rotate.h" +#include "vignetting.h" +#include "toolbar.h" +#include "lensgeom.h" +#include "lensgeomlistener.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 ImageAreaToolListener { + + protected: + + WhiteBalance* whitebalance; + Vignetting* vignetting; + LensGeometry* lensgeom; + LensProfilePanel* lensProf; + Rotate* rotate; + Distortion* distortion; + PerspCorrection* perspective; + CACorrection* cacorrection; + HLRecovery* hlrecovery; + Vibrance* vibrance; + ChMixer* chmixer; + 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); + 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 & 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); + + // 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) { if (ipc) ipc->getAutoWB (temp, green); } + 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; } + 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..b8543d5dd --- /dev/null +++ b/rtgui/vibrance.cc @@ -0,0 +1,385 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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) { + + 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); + + 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, bool psthreshdadd) { + 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..20b08f0a6 --- /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 amountadd, bool passadd, bool psthreshdadd); + 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..2e0b79e8e --- /dev/null +++ b/rtgui/vignetting.cc @@ -0,0 +1,145 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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) { + + 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 = (int)amount->getValue (); + pp->vignetting.radius = (int)radius->getValue (); + pp->vignetting.strength = (int)strength->getValue (); + pp->vignetting.centerX = (int)centerX->getValue (); + pp->vignetting.centerY = (int)centerY->getValue (); + + 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) + listener->panelChanged (EvVignetting, Glib::ustring::compose ("%1=%5\n%2=%6\n%3=%7\n%4=%8 %9", M("TP_VIGNETTING_AMOUNT"), M("TP_VIGNETTING_RADIUS"), M("TP_VIGNETTING_STRENGTH"), M("TP_VIGNETTING_CENTER"), (int)amount->getValue(), (int)radius->getValue(), (int)strength->getValue(), (int)centerX->getValue(), (int)centerY->getValue())); +} + +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..928c8f3cb --- /dev/null +++ b/rtgui/wbprovider.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 _WBPROVIDER_ +#define _WBPROVIDER_ + + +class WBProvider { + + public: + virtual void getAutoWB (double& temp, double& green) {} + 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 100644 index 000000000..55207c47c --- /dev/null +++ b/rtgui/whitebalance.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 "whitebalance.h" +#include +#include "rtimage.h" +#include "options.h" +#include "../rtengine/safegtk.h" + +#define MINTEMP 2000 //1200 +#define MAXTEMP 25000 //12000 +#define MINGREEN 0.02 +#define MAXGREEN 5.0 + +extern Glib::ustring argv0; + +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_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; ishow (); + 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); + + custom_green = new double[WBParams::wbEntries.size()]; + 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_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_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[i] = 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); + + temp = Gtk::manage (new Adjuster (M("TP_WBALANCE_TEMPERATURE"), MINTEMP, MAXTEMP, 5, 4750)); + green = Gtk::manage (new Adjuster (M("TP_WBALANCE_GREEN"), MINGREEN, MAXGREEN, 0.001, 1.0)); + temp->show (); + green->show (); + + pack_start (*temp); + pack_start (*green); + + temp->setAdjusterListener (this); + green->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) ); +} + +WhiteBalance::~WhiteBalance () { + delete[] custom_green; +} + +void WhiteBalance::adjusterChanged (Adjuster* a, double newval) { + + int tVal = (int)temp->getValue(); + double gVal = green->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) { + if (!ppMethod || a==temp || (ppMethod->type==WBT_CAMERA || ppMethod->type==WBT_AUTO) ) { + methconn.block(true); + opt = setActiveMethod(wbCustom->GUILabel); + methconn.block(false); + } + } + + //cache custom WB setting to allow its recall + if (a==temp) + cache_customTemp (tVal); + else + cache_customGreen (gVal); + + 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())); + } +} + +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); + } + 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); + if (batchMode) { + temp->setEditedState (UnEdited); + green->setEditedState (UnEdited); + } + } + break; + case WBT_AUTO: + if (wbp) { + double ctemp, cgreen; + wbp->getAutoWB (ctemp, cgreen); + if (ctemp != -1.0) { + temp->setValue (temp->getAddMode() ? 0.0 : (int)ctemp); + green->setValue (green->getAddMode() ? 0.0 : cgreen); + } + if (batchMode) { + temp->setEditedState (UnEdited); + green->setEditedState (UnEdited); + } + } + break; + case WBT_CUSTOM: + if (custom_temp>0){ + temp->setValue (temp->getAddMode() ? 0.0 : custom_temp); + } + green->setValue (green->getAddMode() ? 0.0 : custom_green[methodId]); + if (batchMode) { + temp->setEditedState (Edited); + green->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 : custom_green[methodId]); + if (batchMode) { + temp->setEditedState (Edited); + green->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) { + + methconn.block (true); + + if (pedited) { + // By default, temperature and green are said "UnEdited", but it may change later + temp->setEditedState (UnEdited); + green->setEditedState (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 (pp->wb.temperature); + green->setValue (pp->wb.green); + 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); + } + //cache_customWB (pp->wb.temperature, pp->wb.green); + break; + case WBT_CAMERA: + if (wbp) { + double ctemp; double cgreen; + wbp->getCamWB (ctemp, cgreen); + + // 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); + + //cache_customWB ((int)ctemp, cgreen); // this will be used to set initial Custom WB setting + } + break; + case WBT_AUTO: + if (wbp) { + double ctemp; double cgreen; + wbp->getAutoWB (ctemp, cgreen); + + if (ctemp != -1.0) { + // Set the automatics temperature value, or 0.0 if in ADD mode + temp->setValue (temp->getAddMode() ? 0.0 : ctemp); + // Set the automatics green value, or 0.0 if in ADD mode + green->setValue (green->getAddMode() ? 0.0 : cgreen); + } + + //cache_customWB ((int)ctemp, cgreen); // this will be used to set initial Custom WB setting + } + 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); + + // The user may have changed the green value even for predefined WB values + if (pedited) { + green->setEditedState (pedited->wb.green ? Edited : UnEdited); + } + //cache_customGreen (pp->wb.green); + break; + } + } + methconn.block (false); +} + +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.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 (); + +} + +void WhiteBalance::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + if (wbp && defParams->wb.method == "Camera") { + double ctemp; double cgreen; + wbp->getCamWB (ctemp, cgreen); + 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); + 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); + } + else { + temp->setDefaultEditedState (Irrelevant); + green->setDefaultEditedState (Irrelevant); + } +} + +void WhiteBalance::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + temp->showEditedCB (); + green->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);" + 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) { + + temp->setAddMode(tempadd); + green->setAddMode(greenadd); +} + +void WhiteBalance::trimValues (rtengine::procparams::ProcParams* pp) { + + temp->trimValue(pp->wb.temperature); + green->trimValue(pp->wb.green); +} + +inline void WhiteBalance::cache_customTemp(int temp) { + custom_temp = temp; +} + +void WhiteBalance::cache_customGreen(double green) { + Gtk::TreeModel::Row row = getActiveMethod(); + if (row == refTreeModel->children().end()) return; + + custom_green[row[methodColumns.colId]] = green; + //printf("WhiteBalance::cache_customWB(%d, %f): the \"green\" value of \"%s\" has been set to: %f\n", temp, green, row[methodColumns.colLabel], custom_green[row[methodColumns.colId]]); +} + +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..1da7012f3 --- /dev/null +++ b/rtgui/whitebalance.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 _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; + Gtk::Button* spotbutton; + int opt; + double nextTemp; + double nextGreen; + WBProvider *wbp; + SpotWBListener* wblistener; + sigc::connection methconn; + int custom_temp; + double* custom_green; + 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 + 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); + 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..86276a25f --- /dev/null +++ b/tools/RTProfileBuilderSample.cs @@ -0,0 +1,276 @@ +#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 2010-11-15) *** +// 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++]; + + // 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 camera = args[argNo++]; + #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..332b4cc02 --- /dev/null +++ b/tools/benchmarkRT @@ -0,0 +1,256 @@ +#!/usr/bin/env bash +# Use this Bash script to test RT processing speed. +# Written by DrSlony +# 2012-02-10 +# www.seeitmyway.org +# 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=3 + +howto() { + fold -s < - Specify the CMAKE_BUILD_TYPE. + The default value is "release". + + Valid types are: + release + debug + minsizerel + relwithdebuginfo + + -e - Specify the whole path to (but excluding) the "rawtherapee" + executable. + e.g. "-e $HOME/rt_${branch}_${buildType}" + + -h - Print this help screen. + + -i - Input file name. 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 www.rawtherapee.com + + -m - Path to your clone of the RawTherapee source code repository. + The default path is ~/rawtherapee + If you do not specify a path and ~/rawtherapee is not found, it + will be cloned. + + -r - You can try out any revision of RawTherapee. + + Valid values are digits or the word "tip" (excluding quotation + marks), e.g. + 1234 + tip + + -s - Input sidecar file name. The name of the PP3 or XMP file by + which the input file must be developed. + This can be a file on your hard drive or a url. + 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 files and existing RT clone dir + ./benchmarkRT -b release -i kittens.raw -s kittens.raw.pp3 -m /home/fruitloops/rawtherapee-clone -r 4.0.0 + +Further help: + If you need further help, discover bugs or want to request new functionality + in 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 +} + +buildRT() { + [[ ! -e "${repo}/.hg/hgrc" ]] && { + printf "Error: Cannot find the RawTherapee source code repository in ${repo}\nEither run this script using the -m option, or proceed and have the source code repository cloned automatically.\n" | fold -s + read -p "Do you want to proceed? y/n: " YN + [[ "$YN" != y ]] && exit 1 + [[ ! -w /tmp ]] && { printf "Error: /tmp is not writable.\n"; exit 1; } + repo="${tmpDir}/repo" + hg clone https://rawtherapee.googlecode.com/hg/ "$repo" + } + cd "$repo" + hg pull + hg update -r "$revision" || { + printf "About to run \"hg update -C\" which will undo any changes you made to the cloned source code repository. YOU MIGHT LOSE YOUR WORK!\n" + read -p "Do you want to undo all uncommitted changes? y/n: " YN + [[ "$YN" != y ]] && exit 1 + hg update -C + hg update -r "$revision" || { printf "Something went wrong while trying to update your cloned source code repository. Exiting.\n"; exit 1; } + } + make clean + ./clean.sh + verLatestTag="`hg parents --template '{LATESTTAG}'`" + verMajor="${verLatestTag%%.*}" + cmake -DCMAKE_BUILD_TYPE="$buildType" -DPROC_TARGET_NUMBER:STRING=2 -DCMAKE_INSTALL_PREFIX=rawtherapee -DBUILD_BUNDLE=ON -DBINDIR=. -DDATADIR=. -DCACHE_NAME_SUFFIX="$verMajor" + cpuCount="`grep -c 'processor' /proc/cpuinfo`" + make -j"$cpuCount" install + mv "$buildType" "${tmpDir}/rt_${branch}_${buildType}" + rtExe="${tmpDir}/rt_${branch}_${buildType}/rawtherapee" +} + +while getopts "e:h?r:i:s:m:b:" opt; do + case "$opt" in + e) customExeDir="$OPTARG" + ;; + h|\?) + howto + exit 0 + ;; + r) revision="$OPTARG" + buildRT + ;; + i) inFile="$OPTARG" + ;; + s) sidecarCustom="$OPTARG" + ;; + m) repo="$OPTARG" + ;; + b) buildType="$OPTARG" + ;; + esac +done + +shift $((OPTIND-1)) + +[ "$1" = "--" ] && shift + +# tmpDir = /tmp/rawtherapee-benchmark +# if buildRT got called then repo = "${tmpDir}/repo" else repo = ${HOME}/rawtherapee + +inFileName="`basename ${inFile}`" + +if [[ ! -e "${tmpDir}" ]]; then + if [[ ! -w /tmp ]]; then + printf "Error: /tmp is not writable.\n" + exit 1 + fi + mkdir "$tmpDir" +fi + +cd "$tmpDir" + +[[ ${inFile} = http* ]] && { + [[ ! -e "${tmpDir}/${inFileName}" ]] && { + printf "${inFileName} not found in ${tmpDir}, downloading it.\n" + [[ ! -w /tmp ]] && { printf "Error: /tmp is not writable.\n"; exit 1; } + [[ ! -e "$tmpDir" ]] && mkdir "$tmpDir" + cd "$tmpDir" + wget -c --trust-server-names "$inFile" + echo + } +} + +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" + [[ ! -w /tmp ]] && { printf "Error: /tmp is not writable.\n"; exit 1; } + [[ ! -e "$tmpDir" ]] && mkdir "$tmpDir" + cd "$tmpDir" + wget -c --trust-server-names "$sidecarCustom" + fi + else # else if sidecarCustom does not start with an http + [[ ! -e "${sidecarCustom}" ]] && { # then check if it exists + printf "You specified \"-i ${sidecarCustom}\" but it doesn't exist." + exit 1 + } + unset sidecarFiles # just to be sure, since custom supports only 1 file. + sidecarDir="" + sidecarFiles="${sidecarCustom}" + fi +else # if sidecarCustom was not specified, use the ones in sidecarDefault + sidecarDirs=("${tmpDir}/rt_${branch}_${buildType}/profiles/" "${tmpDir}/" "${repo}/rt_${branch}_${buildType}/profiles/" "${repo}/rtdata/profiles/" "$HOME/.config/RawTherapee4/profiles/") + for dir in "${sidecarDirs[@]}"; do + for sidecar in "${sidecarDefault[@]}"; do + # echo "Checking for ${sidecar} in ${dir}" + if [[ -f "${dir}${sidecar}" ]]; then + sidecarDir="$dir" + found="true" + # echo "Found sidecar ${sidecar} in ${sidecarDir[@]}" + fi + done + [[ -n $found ]] && break + done + # if the loop above did not find a Neutral.pp3 anywhere, then we download one to $tmpDir + [[ -z $found ]] && { + wget -c --trust-server-names "http://code.google.com/p/rawtherapee/source/browse/rtdata/profiles/Neutral.pp3" "http://code.google.com/p/rawtherapee/source/browse/rtdata/profiles/Default.pp3" + sidecarDir="${tmpDir}/" + } + sidecarFiles=("${sidecarDefault[@]}") +fi + +rtExeDirs=("${customExeDir}" "${tmpDir}/rt_${branch}_${buildType}" "$HOME/rt_${branch}_${buildType}" "${repo}/rt_${branch}_${buildType}" "${repo}/release" "$HOME/rawtherapee/") +for rtExeDir in "${rtExeDirs[@]}"; do + # test below prevents looking for RT in empty rtExeDir variables, so the printf doesn't report "Checking for RawTherapee executable in " with no dir. + [[ $rtExeDir ]] && { + if [[ -x "${rtExeDir}/${rtExe}" ]]; then + printf "%s\n" "Using RawTherapee executable: ${rtExeDir}/${rtExe}" + break + else + printf "%s\n" "Checking for RawTherapee executable in $rtExeDir" + fi + } +done + +if [[ ! -x "${rtExeDir}/${rtExe}" ]]; then + printf "%s\n" "Could not find the RawTherapee executable. Either re-run this script using the -e flag, or continue to have this script clone the source code repository and compile RawTherapee for you. For this to work, you need to have the correct dependencies installed - see http://rawtherapee.com/forum/viewtopic.php?f=10&t=3001#p22213" | fold -s + read -p "Do you want to proceed? y/n: " YN + [[ "$YN" = y ]] && buildRT || exit 0 +fi + +printf "%s\n" "--------------------------------------------------------------------------" "" "Benchmark of RawTherapee" +printf "%s\n" "`uname -srvmpio`" "" + +#rtATBdirs=("${tmpDir}/rt_${branch}_${buildType}" "$HOME/rt_${branch}_${buildType}" "${repo}/rt_${branch}_${buildType}" "${repo}/release" "$HOME/rawtherapee") +#for rtATBdir in "${rtATBdirs[@]}"; do +# if [[ -f "${rtATBdir}/AboutThisBuild.txt" ]]; then +# printf "%s\n" "${rtATBdir}/AboutThisBuild.txt" +# cat "${rtATBdir}/AboutThisBuild.txt" +# break +# fi +#done + +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 + printf "%s\n" "Sidecar[s]: ${sidecarDir}${sidecar}" +done +echo + +unset sidecar +for sidecar in "${sidecarFiles[@]}"; do + unset benchmark + for (( i=1; i<=${runs}; i++ )); do + # printf "%s\n" "rtExe is $rtExe" "tmpDir is $tmpDir" "sidecarDir is $sidecarDir" "sidecar is $sidecar" "outFileFormat is $outFileFormat" "tmpDir is $tmpDir" "inFileName is $inFileName" + benchmark+=("`\time -f %e "${rtExeDir}/${rtExe}" -o "$tmpDir" -p "${sidecarDir}${sidecar}" "$outFileFormat" -Y -c "${tmpDir}/${inFileName}" 2>&1 >/dev/null`") + printf "%b\n" "Benchmark ${sidecar} ${i}: ${benchmark[$i - 1]}" + done + avg=$( { printf "scale=2; ("; IFS="+"; printf %s "${benchmark[*]}"; echo ") / ${#benchmark[@]}"; } | bc) + printf "%b\n" "Benchmark ${sidecar} average:\t${avg}" +done + +printf "Total runtime:\t`IFS=+; bc -l <<< "${benchmark[*]}"`\n" diff --git a/tools/buildRT b/tools/buildRT new file mode 100755 index 000000000..c1f30f897 --- /dev/null +++ b/tools/buildRT @@ -0,0 +1,289 @@ +#!/usr/bin/env bash +# Written by DrSlony +# Version 2.4, 2012-06-28 +# Please report bugs or enhancements to http://code.google.com/p/rawtherapee/issues/list +# www.rawtherapee.com +# www.londonlight.org + +checkDeps () { + hash hg 2>/dev/null || { echo >&2 "Mercurial not found, install Mercurial first and then re-run this script."; exit 1; } + hash curl 2>/dev/null || { echo >&2 "Curl not found, install curl first and then re-run this script."; exit 1; } +} + +getBranches () { + branches=() + while read branch _; do + branches+=("$branch") + done < <(curl -s 'https://rawtherapee.googlecode.com/hg/?cmd=branchmap'; echo) +} + +hgClone () { + [[ -d "${repo}" ]] || { echo "${repo} not found, cloning from GoogleCode"; hg clone https://rawtherapee.googlecode.com/hg/ "${repo}"; } + cd "${repo}" || exit 1 +} + +menu () { + num="1" + # list[0] is manually set to clone to avoid columns, so we make a bogus one and hide it so that the index will match the list entries + list[0]="im hungry omnonom" + buildTypes=("release" "debug") + for branch in "${branches[@]}"; do + for buildType in "${buildTypes[@]}"; do + list+=("$num - ${branch} - ${buildType}") + ((num++)) + done + done + ((num--)) # cause of num++ in the for loop increasing a number after the last list item + + printf "%s\n------------------------------------------\n# - branch - build type\n------------------------------------------\n" + printf "%s\n" "0 - only clone the repository and exit" + printf "%s\n" "${list[@]:1}" | column -t + printf "%s\n" "------------------------------------------" "" "If you don't know which option to choose, then choose the \"default\" branch, \"release\" build type. Enter your choices, each number separated by a single space, e.g. 7 8" "" | fold -s + read -p "Your choices: " -a choiceNumbers + + #sanitize + choiceNumbers=${choiceNumbers//[^0-9 ]/} + echo +} + +compile () { + for choiceNumber in ${choiceNumbers[@]} + do + [[ $choiceNumber = 0 ]] && { + printf "%s\n" "Repository cloned." + hg parents --template 'RawTherapee-{latesttag}.{latesttagdistance} Latest tag: {latesttag}, Latest tag distance: {latesttagdistance}, Changeset: {rev}:{node|short}\n' + exit 0; + } + + read _ _ branch _ buildType < <( echo ${list[$choiceNumber]} ) + echo + printf "%-15b %b\n" "About to compile:" "" "\tChoice number:" "$choiceNumber" "\tBranch:" "$branch" "\tBuild type:" "$buildType" "\tTarget:" "$procTarget" "" "" + rev="`hg parents --template {rev}`" + + # Clean up leftovers from previous successful and 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}" ]] && { + printf "%s\n" "Found old build directory ${HOME}/rt_${branch}_${buildType}" "It must be removed to proceed." + read -p "Do you want to remove it and proceed? y/n: " YN + [[ "$YN" = y ]] && rm -rf "${HOME}/rt_${branch}_${buildType}" || exit 1 + } + + # Clean up old CMake junk + cd "$repo" || exit 1 + echo + printf "%s\n" "Cleaning out old CMake files" + make clean + ./clean.sh + echo + + # print current line in script: + # printf "%s\n" "LINENO is \"$LINENO\", BASH_LINENO[i] is \"${BASH_LINENO[$i]}\". Patched is $patched" + + # if you manually applied a patch, this check avoids having it undone or broken by a hg update + if [[ ! $patched = b ]]; then + printf "%s\n" "Updating the local repository." + hg pull + hg update ${branch} + else + printf "%s\n" "You ran this script with the \"b\" option (\"build-only\")." "Skipping repository update and binary zip creation." + fi + + printf "%s\n" "" "Starting compilation:" + verLatesttag="`hg parents --template '{latesttag}'`" + verLatesttagdistance="`hg parents --template '{latesttagdistance}'`" + verMajor=${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" "$noomp" -DCMAKE_INSTALL_PREFIX="build" -DBUILD_BUNDLE="ON" -DBINDIR="." -DDATADIR="." -DCACHE_NAME_SUFFIX="$verMajor" || { echo "Error during cmake, exiting." >&2; exit 1; } + else + cd "${repo}/build" || exit 1 + cmake -DCMAKE_BUILD_TYPE="$buildType" -DPROC_TARGET_NUMBER="$procTarget" -DCMAKE_C_FLAGS="-pipe" -DCMAKE_CXX_FLAGS="$CMAKE_C_FLAGS" "$noomp" -DCMAKE_INSTALL_PREFIX="build" -DBUILD_BUNDLE="ON" -DBINDIR="." -DDATADIR="." -DCACHE_NAME_SUFFIX="$verMajor" ../ || { echo "Error during cmake, exiting." >&2; 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" "" "" + + # 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 [[ ! $patched = b ]]; 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__ + printf "%s\n" "" "Moving \"${repo}/build/rawtherapee\" to \"${HOME}/rt_${branch}_${buildType}\"" + mv "${repo}/build/rawtherapee" "${HOME}/rt_${branch}_${buildType}" || { printf "%s\n" "" "Could not move \"${repo}/build/rawtherapee\" to \"${HOME}/rt_${branch}_${buildType}\", 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}/rawtherapee" "" "------------------------------------------" + alert "RawTherapee-${verLatesttag}.${verLatesttagdistance} ready.\nChoice number ${choiceNumber}, branch: ${branch}, type: ${buildType}, target: ${procTarget}" + done +} + +checkDistro () { + # 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}; echo "Distribution detected as ${distribution}"; } + done + done + + if [[ -z ${distribution} ]] + then + echo -e "\nCould not automatically detect your distribution.\nPlease enter it below followed immediately by the version\nwithout any spaces or punctuation marks and hit enter,\n.e.g. \"Ubuntu1104\", \"Mint11\" or \"Musix20\"" + read distribution + + #sanitize + distribution=${distribution//[^a-zA-Z0-9]/} + + echo "Distribution entered manually: ${distribution}" + fi +} + +checkBits () { + bits=`uname -m` || { echo -e "Is your system a 32 or 64 bit one?\nEnter 32 or 64 and hit enter."; read bits; bits=${bits//[^0-9]/}; echo "bits entered manually: ${bits}"; } + if [[ $bits = *64* ]] + then + bits=64 + echo "Bits detected as ${bits}" + else + bits=32 + echo "Bits detected as ${bits}" + fi + + [[ $bits != 32 ]] && [[ $bits != 64 ]] && checkBits +} + +setVars () { + unset choiceNumber choiceNumbers buildType buildTypes list branch branches repo + checkDistro + checkBits + repo="${HOME}/rawtherapee" && echo "Repository is set to ${repo}" + cpuCount="`grep -c 'processor' /proc/cpuinfo`" + if (( "$cpuCount" >= 1 && "$cpuCount" <= 8 )); then echo "CPU count detected as ${cpuCount}"; else cpuCount="1"; echo "CPU count set to ${cpuCount}"; fi + procTarget="2" && echo "procTarget set to ${procTarget}" + + if hash notify-send 2>/dev/null; then alert_type="notify-send" + elif hash kdialog 2>/dev/null; then alert_type="kdialog" + elif hash zenity 2>/dev/null; then alert_type="zenity" + elif hash xmessage 2>/dev/null; then alert_type="xmessage" + else alert_type="none" + fi +} + +alert () { + case "$alert_type" in + notify-send) notify-send "RawTherapee" "$1";; + kdialog) kdialog --title "RawTherapee" --passivepopup "`printf "$1"`";; + zenity) zenity --notification --text="`printf "$1"`" &;; + xmessage) xmessage -nearmouse "`printf "$1"`" &;; + none) printf "%b\n" "" "Compilation complete:" "$1";; + esac +} + +finishUp () { + # builds=( /tmp/RawTherapee* ); for f in ${builds[@]}; do echo ${f#/tmp/}; done + if [[ $patched != b ]]; 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" +} + +# PROGRAM START +printf "%s\n\n" "Running the RawTherapee build script." + +while getopts "bh?-nh" opt; do + case $opt in + b) patched="b" + printf "%s\n" "Buildonly flag detected, will not hg pull or update";; + n) noomp="-DOPTION_OMP=OFF" + printf "%s\n" "OpenMP disabled";; + h|\?|\-) printf "%s\n\n" "Usage: $0 [-b] [-n]" "-b stands for \"buildonly mode\", which skips hg pull && hg update, so that you can use this script to easily compile RawTherapee with whatever patches you manually applied." "-n disables OpenMP." | fold -s + exit 0;; + esac +done + +shift $((OPTIND-1)) +[ "$1" = "--" ] && shift + +setVars +checkDeps +getBranches +menu +hgClone +compile +finishUp diff --git a/tools/createicon.exe b/tools/createicon.exe new file mode 100644 index 000000000..0c192be2d Binary files /dev/null and b/tools/createicon.exe differ diff --git a/tools/crossCursor.svg b/tools/crossCursor.svg new file mode 100644 index 000000000..3ae8ab282 --- /dev/null +++ b/tools/crossCursor.svg @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/tools/edited.png b/tools/edited.png new file mode 100644 index 000000000..bbc0dae98 Binary files /dev/null and b/tools/edited.png differ diff --git a/tools/editedb.png b/tools/editedb.png new file mode 100644 index 000000000..d9aa74739 Binary files /dev/null and b/tools/editedb.png differ diff --git a/tools/editedw.png b/tools/editedw.png new file mode 100644 index 000000000..9bfdfa5ca Binary files /dev/null and b/tools/editedw.png differ 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..6885b19a5 --- /dev/null +++ b/tools/generateSourceTarball @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +if [[ ! "$1" ]]; then + printf "%s\n" "Usage: $0 " "Example: $0 4.0.10" + exit +fi + +hg update "$1" +tools/generateReleaseInfo +hg archive -X ".hg*" -X "rtgui/config.h" -X "rtgui/version.h" -X "rtdata/rawtherapee.desktop" rawtherapee-"$1".tar +xz -z -9e rawtherapee-"$1".tar +hg update +rm ReleaseInfo.cmake diff --git a/tools/generateTranslationDiffs b/tools/generateTranslationDiffs new file mode 100755 index 000000000..58488fe0f --- /dev/null +++ b/tools/generateTranslationDiffs @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +# +# Append translation differences on the end of all files. Developers should run this script +# after changing default, so that translators can easily see what items need to be translated. +# +# This script should be run from the project root, e.g: +# $ ./tools/generateTranslationDiffs.sh +# +##################### +tmp=temp_file + +cd "rtdata/languages" +if [[ $? != 0 ]]; then + printf "%s\n" "You must run this script from the root of the project." + exit +fi + +# First thing, we want to strip default of any "!" and duplicates. +grep -v '^!' default | sort -Vu > "$tmp" +mv "$tmp" "default" + +printf "%s\n" "Generating differences... this may take a few minutes." + +# Find all already-translated files +find . -not -iname "default" -not -iname "LICENSE" -not -iname "README" -not -iname "*.sh" -not -iname ".*" -not -iname "$tmp" | + +# For every file found +while read x; do + printf "%s\n" "Working on differences for $x" + + # Find every already-translated line (every line that does not start with an "!") in file "$x", then sort and copy the file to "$tmp" + grep -v '^!' "$x" | sort -Vu > "$tmp" + + printf "%s\n" '' '!!!!!!!!!!!!!!!!!!!!!!!!!' '! Untranslated keys follow; remove the ! prefix after an entry is translated.' '!!!!!!!!!!!!!!!!!!!!!!!!!' '' >> "$tmp" + + # Now to delete the already-translated lines and add them to $tmp + # Find every line that is not a comment + grep -v "^#" default | while read -r 'line' + do + # Set "key" to be just the key, without the ";human text" + key="${line%%;*}" + + # Scan the translated file $x for a translated $key + grep -q "^$key" "$x" + + # If it did not find a translated key in $x, + if [[ $? != 0 ]] + then + # then append a "!" to the line and send it to the language file + printf "%s\n" "!${line}" >> "$tmp" + fi + done + + # Replace the old file with the new one, with a section at the end for differences. + mv "$tmp" "$x" +done + +printf "%s\n" "Finished generating differences." diff --git a/tools/head.png b/tools/head.png new file mode 100644 index 000000000..29b5b934a Binary files /dev/null and b/tools/head.png differ diff --git a/tools/headb.png b/tools/headb.png new file mode 100644 index 000000000..9d3fc2d75 Binary files /dev/null and b/tools/headb.png differ diff --git a/tools/headw.png b/tools/headw.png new file mode 100644 index 000000000..bbbc01b2d Binary files /dev/null and b/tools/headw.png differ diff --git a/tools/histogramButtons.svg b/tools/histogramButtons.svg new file mode 100644 index 000000000..231b6dd94 --- /dev/null +++ b/tools/histogramButtons.svg @@ -0,0 +1,273 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/horizontal.svg b/tools/horizontal.svg new file mode 100644 index 000000000..850b9f33e --- /dev/null +++ b/tools/horizontal.svg @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/tools/osx/Icons.icns b/tools/osx/Icons.icns new file mode 100644 index 000000000..49583ca23 Binary files /dev/null and b/tools/osx/Icons.icns differ diff --git a/tools/osx/Info.plist b/tools/osx/Info.plist new file mode 100644 index 000000000..4020ef513 --- /dev/null +++ b/tools/osx/Info.plist @@ -0,0 +1,28 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + start + CFBundleIconFile + Icons.icns + CFBundleIdentifier + com.rawtherapee.rawtherapee + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + RawTherapee + CFBundlePackageType + APPL + CFBundleShortVersionString + 3.0a + CFBundleSignature + APPL + CFBundleVersion + 3.0 Alpha + NSAppleScriptEnabled + NO + + diff --git a/tools/osx/make-app-bundle b/tools/osx/make-app-bundle new file mode 100755 index 000000000..e17d4361c --- /dev/null +++ b/tools/osx/make-app-bundle @@ -0,0 +1,103 @@ +#!/bin/bash +# Function checkLink: +# args: $1 - file +# +# Will loop through all dynamic links for $file, and update each to be relative. +function checkLink { + #echo "checkLink called with $1 $2" + local FILE=$1 + + otool -L $FILE | grep -v "${APP}" | grep -v '/usr/lib' | grep -v '/System/' | grep -v "@executable_path" | cut -f 1 -d ' ' | while read X + do + local NAME=${LIB}/`basename "$X"` + if [ ! -f "${NAME}" ] + then + cp $X "${NAME}" + + #Recursively update the linkage of libraries + checkLink "${NAME}" + fi + done +} + +APP=RawTherapee.app +CONTENTS=${APP}/Contents +RESOURCES=${CONTENTS}/Resources +MACOS=${CONTENTS}/MacOS +BIN=${MACOS}/bin +ETC=${MACOS}/etc +LIB=${MACOS}/lib +SHARE=${MACOS}/share +RELEASE=Release +DMG=rawtherapee_mac32_`date +%F`_`hg -R . branch`_`hg parents --template '{latesttag}i.{latesttagdistance}-{node|short}'`.dmg +EXECUTABLE=rawtherapee + +#Find where MacPorts is installed. We take a known binary (cmake), which is in /bin, and +# go up a level to get the main install folder. +MACPORTS_PREFIX=`which cmake` +MACPORTS_PREFIX=`dirname $MACPORTS_PREFIX` +MACPORTS_PREFIX=`dirname $MACPORTS_PREFIX` + +if [ ! -d ${RELEASE} ]; then + echo "Please run this from the root of the project; i.e. './tools/osx/make-app-bundle'." + exit +fi + +if [ -d "${APP}" ]; then + echo "Removing old application..." + rm -rf "${APP}" +fi +echo "Removing any old disk images..." +rm ${RELEASE}/rawtherapee*.dmg +rm ${RELEASE}/rawtherapee*.dmg.zip + +echo "Making application directory structure..." +mkdir -p "${RESOURCES}" +mkdir -p "${ETC}" +mkdir -p "${LIB}" +mkdir -p "${SHARE}/mime" + +#Copy over non-explicitly linked libraries +echo "Copying libraries from ${MACPORTS_PREFIX}..." +cp -R ${MACPORTS_PREFIX}/lib/pango ${LIB} +cp -R ${MACPORTS_PREFIX}/lib/gtk-2.0 ${LIB} +cp -R ${MACPORTS_PREFIX}/lib/gdk-pixbuf* ${LIB} + +#Copy over mimes (if a mime is copied, and nobody hears, is it really copied?) +echo "Copying shared files from ${MACPORTS_PREFIX}..." +cp -R ${MACPORTS_PREFIX}/share/mime/* ${SHARE}/mime + +#Copy over etc files, and modify as needed +echo "Copying configuration files from ${MACPORTS_PREFIX} and modifying for standalone app bundle..." +cp -R $MACPORTS_PREFIX/etc/gtk-2.0 ${ETC} +cp -R $MACPORTS_PREFIX/etc/pango ${ETC} +ESCAPED_MACPORTS_PREFIX=`echo ${MACPORTS_PREFIX} | sed -e 's/\\//\\\\\\//g'` +sed -i .bak -e "s/${ESCAPED_MACPORTS_PREFIX}/@executable_path/g" ${ETC}/gtk-2.0/gdk-pixbuf.loaders ${ETC}/gtk-2.0/gtk.immodules ${ETC}/pango/pango.modules +echo -e "[Pango]\nModuleFiles = /tmp/${EXECUTABLE}_pango.modules" > ${ETC}/pango/pangorc +rm ${LIB}/gdk-pixbuf-2.0/2.10.0/loaders.cache + +#Copy over the release files +echo "Copying release files..." +cp -R ${RELEASE}/* ${MACOS} + +#Copy application-specific stuff like icons and startup script +echo "Creating required application bundle files..." +cp ./tools/osx/Info.plist ${CONTENTS} +cp tools/osx/Icons.icns ${RESOURCES} +cp tools/osx/start ${MACOS} + +#Copy and relink the explicitly defined libraries +echo "Recursively copying libraries referenced by executable..." +checkLink "${MACOS}/${EXECUTABLE}" + + +#Make a .dmg for distribution and delete the .app +echo "Creating distribution .dmg..." +hdiutil create -srcdir ${APP} ${RELEASE}/${DMG} +echo "Cleaning up..." +rm -rf ${APP} + +cd ${RELEASE} +zip ${DMG}.zip ${DMG} AboutThisBuild.txt + +echo "All done!" diff --git a/tools/osx/start b/tools/osx/start new file mode 100755 index 000000000..b6f40ca65 --- /dev/null +++ b/tools/osx/start @@ -0,0 +1,19 @@ +#!/bin/bash + +CWD=`dirname "$0"` +echo $CWD + +export DYLD_LIBRARY_PATH="${CWD}/lib:$DYLD_LIBRARY_PATH" +export GTK_DATA_PREFIX="${CWD}" +export GTK_DATA_DIRS="${CWD}" +export GTK_EXE_PREFIX="${CWD}" +export GTK_PATH="${CWD}" + +export GTK2_RC_FILES="${CWD}/etc/gtk-2.0/gtkrc" +export GTK_IM_MODULE_FILE="${CWD}/gtk-2.0/gtk.immodules" +export GDK_PIXBUF_MODULE_FILE="${CWD}/etc/gtk-2.0/gdk-pixbuf.loaders" +export PANGO_RC_FILE="${CWD}/etc/pango/pangorc" + +cp "${CWD}/etc/pango/pango.modules" /tmp/rawtherapee_pango.modules + +"${CWD}/rawtherapee" diff --git a/tools/processing.png b/tools/processing.png new file mode 100644 index 000000000..33e8c4ed7 Binary files /dev/null and b/tools/processing.png differ diff --git a/tools/processingb.png b/tools/processingb.png new file mode 100644 index 000000000..d34293483 Binary files /dev/null and b/tools/processingb.png differ diff --git a/tools/processingw.png b/tools/processingw.png new file mode 100644 index 000000000..15954e3e9 Binary files /dev/null and b/tools/processingw.png differ diff --git a/tools/saved.png b/tools/saved.png new file mode 100644 index 000000000..556a93fb5 Binary files /dev/null and b/tools/saved.png differ diff --git a/tools/savedb.png b/tools/savedb.png new file mode 100644 index 000000000..1d5e809c0 Binary files /dev/null and b/tools/savedb.png differ diff --git a/tools/savedw.png b/tools/savedw.png new file mode 100644 index 000000000..1ec8c5d73 Binary files /dev/null and b/tools/savedw.png differ diff --git a/tools/source_icons/README b/tools/source_icons/README new file mode 100644 index 000000000..5836b4670 --- /dev/null +++ b/tools/source_icons/README @@ -0,0 +1,28 @@ +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: + -> colum are separated with a comma + -> first column list the *.png file to be created + -> second column indicates either the width (e.g. w22) or the height (e.g. h16) in pixel for the *.png file + -> third column is optional. It indicates the icon category (e.g. actions, devices, places). If not indicated, the icon is supposed 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 tools/source_icons/scalable /tmp/png +- an archive with all the icons will be created in /tmp/png + +================================ +=== guidelines for icon name === +================================ +- Use stock item name when prebuilt icon exists (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 icon size as a suffix to name icon (colour.png and nor colour-24.png). If needed, use the suffix -large or -small (gtk-close-small.png). diff --git a/tools/source_icons/scalable/PanelEnding.file b/tools/source_icons/scalable/PanelEnding.file new file mode 100644 index 000000000..865b12983 --- /dev/null +++ b/tools/source_icons/scalable/PanelEnding.file @@ -0,0 +1 @@ +PanelEnding.png,h28 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..078fceebd --- /dev/null +++ b/tools/source_icons/scalable/beforeafter.file @@ -0,0 +1 @@ +beforeafter.png,w22 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..5e1ed7053 --- /dev/null +++ b/tools/source_icons/scalable/cglabel0.file @@ -0,0 +1 @@ +cglabel0.png,h10 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..d55309573 --- /dev/null +++ b/tools/source_icons/scalable/cglabel1.file @@ -0,0 +1 @@ +cglabel1.png,h10 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..1940882a6 --- /dev/null +++ b/tools/source_icons/scalable/cglabel2.file @@ -0,0 +1 @@ +cglabel2.png,h10 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..a0a888e02 --- /dev/null +++ b/tools/source_icons/scalable/cglabel3.file @@ -0,0 +1 @@ +cglabel3.png,h10 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..323616550 --- /dev/null +++ b/tools/source_icons/scalable/cglabel4.file @@ -0,0 +1 @@ +cglabel4.png,h10 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..20017c190 --- /dev/null +++ b/tools/source_icons/scalable/cglabel5.file @@ -0,0 +1 @@ +cglabel5.png,h10 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..d68002315 --- /dev/null +++ b/tools/source_icons/scalable/clabel0.file @@ -0,0 +1 @@ +clabel0.png,h10 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..25308cc88 --- /dev/null +++ b/tools/source_icons/scalable/clabel1.file @@ -0,0 +1 @@ +clabel1.png,h10 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..7a8100449 --- /dev/null +++ b/tools/source_icons/scalable/clabel2.file @@ -0,0 +1 @@ +clabel2.png,h10 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..77a0cb0cc --- /dev/null +++ b/tools/source_icons/scalable/clabel3.file @@ -0,0 +1 @@ +clabel3.png,h10 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..121575d4b --- /dev/null +++ b/tools/source_icons/scalable/clabel4.file @@ -0,0 +1 @@ +clabel4.png,h10 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..4d89a9ec5 --- /dev/null +++ b/tools/source_icons/scalable/clabel5.file @@ -0,0 +1 @@ +clabel5.png,h10 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..38d9d360b --- /dev/null +++ b/tools/source_icons/scalable/closedhand.file @@ -0,0 +1 @@ +closedhand.png,w22 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..e7685e5b8 --- /dev/null +++ b/tools/source_icons/scalable/colour.file @@ -0,0 +1 @@ +colour.png,w24 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..2c3af9520 --- /dev/null +++ b/tools/source_icons/scalable/crop-auto.file @@ -0,0 +1 @@ +crop-auto.png,h18 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..16d60cf10 --- /dev/null +++ b/tools/source_icons/scalable/crop.file @@ -0,0 +1 @@ +crop.png,w22 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/crossed-arrows-in.file b/tools/source_icons/scalable/crossed-arrows-in.file new file mode 100644 index 000000000..8edfdde62 --- /dev/null +++ b/tools/source_icons/scalable/crossed-arrows-in.file @@ -0,0 +1 @@ +crossed-arrows-in.png,w22 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..c9d3b3221 --- /dev/null +++ b/tools/source_icons/scalable/crossed-arrows-out.file @@ -0,0 +1 @@ +crossed-arrows-out.png,w22 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..f0d2c7b6c --- /dev/null +++ b/tools/source_icons/scalable/curveType-NURBS.file @@ -0,0 +1 @@ +curveType-NURBS.png,w18 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..761307141 --- /dev/null +++ b/tools/source_icons/scalable/curveType-controlPoints.file @@ -0,0 +1 @@ +curveType-controlPoints.png,w18 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..a6118981c --- /dev/null +++ b/tools/source_icons/scalable/curveType-flatLinear.file @@ -0,0 +1 @@ +curveType-flatLinear.png,w18 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..df3d4f34e --- /dev/null +++ b/tools/source_icons/scalable/curveType-linear.file @@ -0,0 +1 @@ +curveType-linear.png,w18 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..7ebc711c6 --- /dev/null +++ b/tools/source_icons/scalable/curveType-parametric.file @@ -0,0 +1 @@ +curveType-parametric.png,w18 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..d48342a33 --- /dev/null +++ b/tools/source_icons/scalable/curveType-spline.file @@ -0,0 +1 @@ +curveType-spline.png,w18 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..604baf302 --- /dev/null +++ b/tools/source_icons/scalable/detail.file @@ -0,0 +1 @@ +detail.png,w24 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..4e1be8d3c --- /dev/null +++ b/tools/source_icons/scalable/distorsion.file @@ -0,0 +1 @@ +distorsion.png,w22 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..50f15d361 --- /dev/null +++ b/tools/source_icons/scalable/distortion-auto.file @@ -0,0 +1 @@ +distortion-auto.png,h18 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/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..9ccf82b1f --- /dev/null +++ b/tools/source_icons/scalable/edited.file @@ -0,0 +1,2 @@ +edited.png,w18 +edited-small.png,h10 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..c68c67d2f --- /dev/null +++ b/tools/source_icons/scalable/editedg.file @@ -0,0 +1 @@ +editedg-small.png,h10 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..6cf77b756 --- /dev/null +++ b/tools/source_icons/scalable/editednot.file @@ -0,0 +1 @@ +editednot-small.png,h10 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..771e33ceb --- /dev/null +++ b/tools/source_icons/scalable/editednotg.file @@ -0,0 +1 @@ +editednotg-small.png,h10 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..3e4b9d150 --- /dev/null +++ b/tools/source_icons/scalable/exposure.file @@ -0,0 +1 @@ +exposure.png,w24 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..e1bc5ce8e --- /dev/null +++ b/tools/source_icons/scalable/filter.file @@ -0,0 +1 @@ +filter.png,w22 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..7c4efc1d6 --- /dev/null +++ b/tools/source_icons/scalable/filterclear.file @@ -0,0 +1 @@ +filterclear.png,w22 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..8c6285c92 --- /dev/null +++ b/tools/source_icons/scalable/grayrated.file @@ -0,0 +1 @@ +grayrated.png,h10 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..b49193f13 --- /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 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..db681bcc1 --- /dev/null +++ b/tools/source_icons/scalable/gtk-close.file @@ -0,0 +1,3 @@ +gtk-close.png,w16 +gtk-close-small.png,h13 +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..f9779f136 --- /dev/null +++ b/tools/source_icons/scalable/gtk-color-picker.file @@ -0,0 +1,2 @@ +gtk-color-picker.png,w22 +gtk-color-picker-small.png,h18 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..43f438346 --- /dev/null +++ b/tools/source_icons/scalable/gtk-copy.file @@ -0,0 +1,2 @@ +edit-copy.png,w22 +gtk-copy.png,w22 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..0baa3044f --- /dev/null +++ b/tools/source_icons/scalable/gtk-delete.file @@ -0,0 +1,2 @@ +trash.png,w22 +trash-show-empty.png,w22 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..099e23f73 --- /dev/null +++ b/tools/source_icons/scalable/gtk-execute.file @@ -0,0 +1 @@ +processing.png,w20 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..2af70257d --- /dev/null +++ b/tools/source_icons/scalable/gtk-file.file @@ -0,0 +1 @@ +rtwindow.png,w20 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..552a3cea2 --- /dev/null +++ b/tools/source_icons/scalable/gtk-fullscreen.file @@ -0,0 +1 @@ +fullscreen.png,w22 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..edb6c386a --- /dev/null +++ b/tools/source_icons/scalable/gtk-goto-first.file @@ -0,0 +1 @@ +toleftend.png,h16 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..ca0a1e4f9 --- /dev/null +++ b/tools/source_icons/scalable/gtk-goto-last.file @@ -0,0 +1 @@ +torightend.png,h16 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..f6ee79d30 --- /dev/null +++ b/tools/source_icons/scalable/gtk-leave-fullscreen.file @@ -0,0 +1 @@ +fullscreen-exit.png,w22 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..f23261c2b --- /dev/null +++ b/tools/source_icons/scalable/gtk-media-play.file @@ -0,0 +1 @@ +gtk-media-play.png,w13 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..15374b760 --- /dev/null +++ b/tools/source_icons/scalable/gtk-media-stop.file @@ -0,0 +1 @@ +gtk-media-stop.png,w13 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..f099a0ad7 --- /dev/null +++ b/tools/source_icons/scalable/gtk-paste.file @@ -0,0 +1,2 @@ +edit-paste.png,w22 +gtk-paste.png,w22 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..ee4d7cbef --- /dev/null +++ b/tools/source_icons/scalable/gtk-preferences.file @@ -0,0 +1 @@ +gtk-preferences.png,w22 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..e65153cb4 --- /dev/null +++ b/tools/source_icons/scalable/gtk-remove-red.file @@ -0,0 +1 @@ +list-remove-red-small.png,w12 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..be6a39b76 --- /dev/null +++ b/tools/source_icons/scalable/gtk-save.file @@ -0,0 +1,2 @@ +gtk-save-large.png,w22 +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..cc8383b74 --- /dev/null +++ b/tools/source_icons/scalable/gtk-undo-rtl.file @@ -0,0 +1,2 @@ +gtk-undo-rtl.png,h16 +gtk-undo-rtl-small.png,h11 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..95870e055 --- /dev/null +++ b/tools/source_icons/scalable/gtk-undo.file @@ -0,0 +1,2 @@ +gtk-undo-ltr.png,h16 +gtk-undo-ltr-small.png,h11 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..3f4b9eb43 --- /dev/null +++ b/tools/source_icons/scalable/gtk-undoall-ltr.file @@ -0,0 +1 @@ +gtk-undoall-ltr.png,w16 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..2b28cdc6a --- /dev/null +++ b/tools/source_icons/scalable/gtk-undoall-rtl.file @@ -0,0 +1 @@ +gtk-undoall-rtl.png,w16 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..2b2c52b4f --- /dev/null +++ b/tools/source_icons/scalable/gtk-zoom-100.file @@ -0,0 +1 @@ +gtk-zoom-100.png,w22 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..7bf025a7c --- /dev/null +++ b/tools/source_icons/scalable/gtk-zoom-100.svg @@ -0,0 +1,599 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + 1 + + + + + + + + + + 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..05db5237f --- /dev/null +++ b/tools/source_icons/scalable/gtk-zoom-fit.file @@ -0,0 +1 @@ +gtk-zoom-fit.png,w22 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..e99314b1e --- /dev/null +++ b/tools/source_icons/scalable/gtk-zoom-in.file @@ -0,0 +1 @@ +gtk-zoom-in.png,w22 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..a269c6732 --- /dev/null +++ b/tools/source_icons/scalable/gtk-zoom-out.file @@ -0,0 +1 @@ +gtk-zoom-out.png,w22 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..be56cfdc7 --- /dev/null +++ b/tools/source_icons/scalable/histBar.file @@ -0,0 +1 @@ +histBar.png,w10 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..248cd289e --- /dev/null +++ b/tools/source_icons/scalable/histBarg.file @@ -0,0 +1 @@ +histBarg.png,w10 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..007abf73b --- /dev/null +++ b/tools/source_icons/scalable/histBlue.file @@ -0,0 +1 @@ +histBlue.png,w10 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..a2af682a2 --- /dev/null +++ b/tools/source_icons/scalable/histBlueg.file @@ -0,0 +1 @@ +histBlueg.png,w10 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..8be7a8c24 --- /dev/null +++ b/tools/source_icons/scalable/histFull.file @@ -0,0 +1 @@ +histFull.png,w10 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..97658750c --- /dev/null +++ b/tools/source_icons/scalable/histFullg.file @@ -0,0 +1 @@ +histFullg.png,w10 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..1170d414c --- /dev/null +++ b/tools/source_icons/scalable/histGreen.file @@ -0,0 +1 @@ +histGreen.png,w10 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..37d41af88 --- /dev/null +++ b/tools/source_icons/scalable/histGreeng.file @@ -0,0 +1 @@ +histGreeng.png,w10 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..7565bc25a --- /dev/null +++ b/tools/source_icons/scalable/histRaw.file @@ -0,0 +1 @@ +histRaw.png,w10 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..fc0864248 --- /dev/null +++ b/tools/source_icons/scalable/histRawg.file @@ -0,0 +1 @@ +histRawg.png,w10 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..d8f6aeeb1 --- /dev/null +++ b/tools/source_icons/scalable/histRed.file @@ -0,0 +1 @@ +histRed.png,w10 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..267755a1c --- /dev/null +++ b/tools/source_icons/scalable/histRedg.file @@ -0,0 +1 @@ +histRedg.png,w10 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..aecd59611 --- /dev/null +++ b/tools/source_icons/scalable/histValue.file @@ -0,0 +1 @@ +histValue.png,w10 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..6879914e7 --- /dev/null +++ b/tools/source_icons/scalable/histValueg.file @@ -0,0 +1 @@ +histValueg.png,w10 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/image-editor.file b/tools/source_icons/scalable/image-editor.file new file mode 100644 index 000000000..f0f93d4dd --- /dev/null +++ b/tools/source_icons/scalable/image-editor.file @@ -0,0 +1 @@ +image-editor.png,w22 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..90c0da21b --- /dev/null +++ b/tools/source_icons/scalable/info.file @@ -0,0 +1 @@ +info.png,w22 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..b557fade6 --- /dev/null +++ b/tools/source_icons/scalable/lock-off.file @@ -0,0 +1 @@ +lock-off.png,h10 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..d5ac33f01 --- /dev/null +++ b/tools/source_icons/scalable/lock-on.file @@ -0,0 +1 @@ +lock-on.png,h10 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..1e54e9fd2 --- /dev/null +++ b/tools/source_icons/scalable/meta.file @@ -0,0 +1 @@ +meta.png,w24 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/new-detail-window.file b/tools/source_icons/scalable/new-detail-window.file new file mode 100644 index 000000000..1f0a542d4 --- /dev/null +++ b/tools/source_icons/scalable/new-detail-window.file @@ -0,0 +1 @@ +new-detail-window.png,w22 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..8b792946a --- /dev/null +++ b/tools/source_icons/scalable/openhand.file @@ -0,0 +1 @@ +openhand.png,w22 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..34fead066 --- /dev/null +++ b/tools/source_icons/scalable/panel-to-bottom.file @@ -0,0 +1 @@ +panel-to-bottom.png,w22 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..9fc879f5c --- /dev/null +++ b/tools/source_icons/scalable/panel-to-left.file @@ -0,0 +1 @@ +panel-to-left.png,h22 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..fbaa341e0 --- /dev/null +++ b/tools/source_icons/scalable/panel-to-right.file @@ -0,0 +1 @@ +panel-to-right.png,h22 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..4de3e9260 --- /dev/null +++ b/tools/source_icons/scalable/panel-to-top.file @@ -0,0 +1 @@ +panel-to-top.png,w22 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/popuparrow.file b/tools/source_icons/scalable/popuparrow.file new file mode 100644 index 000000000..a33c25a9a --- /dev/null +++ b/tools/source_icons/scalable/popuparrow.file @@ -0,0 +1 @@ +popuparrow.png,h6 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..3b4b24016 --- /dev/null +++ b/tools/source_icons/scalable/processing-pause.file @@ -0,0 +1 @@ +processing-pause.png,w20 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..bf42ef9c5 --- /dev/null +++ b/tools/source_icons/scalable/processing-play.file @@ -0,0 +1 @@ +processing-play.png,w20 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..0d7164a09 --- /dev/null +++ b/tools/source_icons/scalable/processing-thumbnail.file @@ -0,0 +1 @@ +processing-thumbnail.png,w18 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/rated.file b/tools/source_icons/scalable/rated.file new file mode 100644 index 000000000..9caaa5282 --- /dev/null +++ b/tools/source_icons/scalable/rated.file @@ -0,0 +1 @@ +rated.png,h10 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..71fc46456 --- /dev/null +++ b/tools/source_icons/scalable/ratednot.file @@ -0,0 +1 @@ +ratednot.png,h10 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..136adbb25 --- /dev/null +++ b/tools/source_icons/scalable/ratednotg.file @@ -0,0 +1 @@ +ratednotg.png,h10 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..675289269 --- /dev/null +++ b/tools/source_icons/scalable/raw.file @@ -0,0 +1 @@ +raw.png,w24 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..89432ea53 --- /dev/null +++ b/tools/source_icons/scalable/refresh-red.file @@ -0,0 +1 @@ +refresh-red.png,h13 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..3fc99e981 --- /dev/null +++ b/tools/source_icons/scalable/refresh-white.file @@ -0,0 +1 @@ +refresh-white.png,h13 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/stock-flip-horizontal.file b/tools/source_icons/scalable/stock-flip-horizontal.file new file mode 100644 index 000000000..10da14b88 --- /dev/null +++ b/tools/source_icons/scalable/stock-flip-horizontal.file @@ -0,0 +1 @@ +stock-flip-horizontal.png,w22 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..ac00ea29c --- /dev/null +++ b/tools/source_icons/scalable/stock-flip-vertical.file @@ -0,0 +1 @@ +stock-flip-vertical.png,w22 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..c2a4f8db9 --- /dev/null +++ b/tools/source_icons/scalable/stock-rotate-270.file @@ -0,0 +1 @@ +stock-rotate-270.png,w22 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..5e24f507f --- /dev/null +++ b/tools/source_icons/scalable/stock-rotate-90.file @@ -0,0 +1 @@ +stock-rotate-90.png,w22 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..a41c40c49 --- /dev/null +++ b/tools/source_icons/scalable/straighten.file @@ -0,0 +1,2 @@ +straighten.png,w22 +straighten-small.png,h18 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..365df73ba --- /dev/null +++ b/tools/source_icons/scalable/transform.file @@ -0,0 +1 @@ +transform.png,w24 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..32831d2e0 --- /dev/null +++ b/tools/source_icons/scalable/trash-show-full.file @@ -0,0 +1 @@ +trash-show-full.png,w22 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..b0c99696c --- /dev/null +++ b/tools/source_icons/scalable/trash-thumbnail.file @@ -0,0 +1 @@ +trash-thumbnail.png,w18 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..1d560fcc1 --- /dev/null +++ b/tools/source_icons/scalable/undelete-rtl.file @@ -0,0 +1 @@ +undelete-rtl.png,w22 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..58ccd7fb8 --- /dev/null +++ b/tools/source_icons/scalable/undelete-thumbnail-rtl.file @@ -0,0 +1 @@ +undelete-thumbnail-rtl.png,w18 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..d93a5ffd3 --- /dev/null +++ b/tools/source_icons/scalable/undelete-thumbnail.file @@ -0,0 +1 @@ +undelete-thumbnail.png,w18 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..4afda7ae5 --- /dev/null +++ b/tools/source_icons/scalable/undelete.file @@ -0,0 +1 @@ +undelete.png,w22 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..f00c43ce7 --- /dev/null +++ b/tools/source_icons/scalable/warnhl.file @@ -0,0 +1 @@ +warnhl.png,w22 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..37db8747b --- /dev/null +++ b/tools/source_icons/scalable/warnsh.file @@ -0,0 +1 @@ +warnsh.png,w22 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..66d3a295b --- /dev/null +++ b/tools/source_icons/scalable/wb-auto.file @@ -0,0 +1 @@ +wb-auto.png,w22 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..9e9215362 --- /dev/null +++ b/tools/source_icons/scalable/wb-camera.file @@ -0,0 +1 @@ +wb-camera.png,w22 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..e67541471 --- /dev/null +++ b/tools/source_icons/scalable/wb-cloudy.file @@ -0,0 +1 @@ +wb-cloudy.png,w22 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..d84fcd118 --- /dev/null +++ b/tools/source_icons/scalable/wb-custom.file @@ -0,0 +1 @@ +wb-custom.png,w22 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..0da5e23a6 --- /dev/null +++ b/tools/source_icons/scalable/wb-flash.file @@ -0,0 +1 @@ +wb-flash.png,w22 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..9c1926282 --- /dev/null +++ b/tools/source_icons/scalable/wb-fluorescent.file @@ -0,0 +1 @@ +wb-fluorescent.png,w22 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..1e7ba8fa3 --- /dev/null +++ b/tools/source_icons/scalable/wb-lamp.file @@ -0,0 +1 @@ +wb-lamp.png,w22 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..1327fd240 --- /dev/null +++ b/tools/source_icons/scalable/wb-led.file @@ -0,0 +1 @@ +wb-led.png,w22 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..0f21c85bd --- /dev/null +++ b/tools/source_icons/scalable/wb-shade.file @@ -0,0 +1 @@ +wb-shade.png,w22 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..026bc82f6 --- /dev/null +++ b/tools/source_icons/scalable/wb-sun.file @@ -0,0 +1 @@ +wb-sun.png,w22 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..a27d226a0 --- /dev/null +++ b/tools/source_icons/scalable/wb-tungsten.file @@ -0,0 +1 @@ +wb-tungsten.png,w22 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/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/tools/tail.png b/tools/tail.png new file mode 100644 index 000000000..a40e93750 Binary files /dev/null and b/tools/tail.png differ diff --git a/tools/tailb.png b/tools/tailb.png new file mode 100644 index 000000000..e22ba7f14 Binary files /dev/null and b/tools/tailb.png differ diff --git a/tools/tailw.png b/tools/tailw.png new file mode 100644 index 000000000..cfadaf6b5 Binary files /dev/null and b/tools/tailw.png differ diff --git a/tools/trash.png b/tools/trash.png new file mode 100644 index 000000000..c185c78e4 Binary files /dev/null and b/tools/trash.png differ diff --git a/tools/trashb.png b/tools/trashb.png new file mode 100644 index 000000000..eb680934e Binary files /dev/null and b/tools/trashb.png differ diff --git a/tools/trashw.png b/tools/trashw.png new file mode 100644 index 000000000..c6393bd36 Binary files /dev/null and b/tools/trashw.png differ diff --git a/tools/undelete.png b/tools/undelete.png new file mode 100644 index 000000000..17f7c62f0 Binary files /dev/null and b/tools/undelete.png differ diff --git a/tools/undeleteb.png b/tools/undeleteb.png new file mode 100644 index 000000000..3119ed6f6 Binary files /dev/null and b/tools/undeleteb.png differ diff --git a/tools/undeletew.png b/tools/undeletew.png new file mode 100644 index 000000000..2bf13763d Binary files /dev/null and b/tools/undeletew.png differ diff --git a/tools/vertical.svg b/tools/vertical.svg new file mode 100644 index 000000000..c8bdaf573 --- /dev/null +++ b/tools/vertical.svg @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + +